immich-app/immich · warning
If using Docker, consider increasing shm_size for the…
Error message
If using Docker, consider increasing shm_size for the database.
What it means
After a VACUUM command fails, the repository logs the failure and this hint suggesting that in Docker the default 64MB shared memory (shm_size) of the Postgres container is often too small for VACUUM operations. The vacuum call swallows the error and continues.
Solutions
- Increase the database container's shm_size (e.g. shm_size: 256mb in docker-compose for the postgres service)
- Run VACUUM manually inside the database container with psql when idle to see the exact error
- Check Postgres logs for the underlying error (out of shared memory, disk full, locks)
- If transient, retry once the database is less loaded
Example fix
// before (docker-compose.yml) database: image: ghcr.io/immich-app/postgres // after database: image: ghcr.io/immich-app/postgres shm_size: 256mb
Defensive patterns
Strategy: retry
Validate before calling
// pre-check shared memory from the host before heavy maintenance
const shmBytes = Number(fs.readFileSync('/dev/shm/../shm_size', 'utf8')) || -1;
// simpler: verify in container
// docker exec immich_postgres df -h /dev/shm → ensure >> 64mb Try / catch
try {
await db.vacuum({ analyze: true, table: 'smart_search' });
} catch (err) {
if (String(err).includes('out of shared memory')) {
logger.warn('Increase Postgres shm_size and retry vacuum');
}
} Prevention
- Set shm_size: 256mb (or higher) on the Postgres Docker service from day one
- Schedule VACUUM/REINDEX during low-traffic windows
- Watch Postgres logs for 'out of shared memory' during maintenance
- Keep disk headroom above the size of the largest table
When it happens
Trigger: vacuum() runs `VACUUM [ANALYZE] [table]` and Postgres raises an error — classically 'out of shared memory' during concurrent operations or VACUUM inside a Dockerized Postgres with low shm_size. Called by reindexVectors after reindexing.
Common situations: Postgres Docker container with default shm_size running VACUUM/ANALYZE on large tables; heavy concurrent index creation exceeding max_locks/shared memory; low disk space during vacuum.
Understand the failure class
Background: Database query failed: Internal Server Error 500s wrapping SQL, Prisma, and connection failures — what to check first — this error's family across 16 libraries.
Related errors
- Column 'embedding' does not exist in table
- Could not retrieve dimension size of column
- Detected an inconsistent media location. For more…
- Device ' ' does not exist. If using Docker, make sure this…
- extension is not installed
AI-assisted analysis of immich-app/immich@e55ac299a4 (2026-09-15).
Data as JSON: /api/errors/56718217dd8c7867.
Report an issue: GitHub.
Appendix: source
Thrown at server/src/repositories/database.repository.ts:255
await sql`ALTER TABLE ${sql.raw(table)} ADD COLUMN embedding real[] NOT NULL`.execute(tx);
}
await sql`ALTER TABLE ${sql.raw(table)} ALTER COLUMN embedding SET DATA TYPE real[]`.execute(tx);
await sql`
ALTER TABLE ${sql.raw(table)}
ALTER COLUMN embedding
SET DATA TYPE vector(${sql.raw(String(dimSize))})`.execute(tx);
await sql.raw(vectorIndexQuery({ vectorExtension, table, indexName, lists })).execute(tx);
});
this.logger.log(`Reindexed ${indexName}`);
void this.vacuum({ table }).catch((error) => this.logger.warn(`Failed to vacuum ${table}: ${error}`));
}
async vacuum({ analyze = false, table }: { analyze?: boolean; table?: keyof DB } = {}): Promise<void> {
try {
await sql`VACUUM ${sql.raw(analyze ? 'ANALYZE' : '')} ${sql.raw(table ?? '')}`.execute(this.db);
} catch (error) {
this.logger.warn(`Failed to vacuum ${table || 'database'}: ${error}`);
this.logger.warn('If using Docker, consider increasing shm_size for the database.');
}
}
reindex(table: keyof DB, { concurrently = false } = {}): Promise<unknown> {
return sql`REINDEX TABLE ${sql.raw(concurrently ? 'CONCURRENTLY' : '')} ${sql.raw(table)}`.execute(this.db);
}
private async getDatabaseName(): Promise<string> {
const { rows } = await sql<{ db: string }>`SELECT current_database() as db`.execute(this.db);
return rows[0].db;
}
getMigrations() {
return this.db.selectFrom('kysely_migrations').select(['name', 'timestamp']).orderBy('name', 'asc').execute();
}
async getSchemaDrift() {
const source = schemaFromCode({View on GitHub (pinned to e55ac299a4)