If your Mastodon instance feels slow during peak hours or returns database timeout errors in the web interface, the default PostgreSQL configuration is likely the culprit. Mastodon relies heavily on database queries for timelines, notifications, and search. Out-of-the-box Postgres settings are designed for a typical web application, not a federated social network that can serve thousands of concurrent requests. This article explains how to adjust key Postgres parameters to handle a busy Mastodon server. You will learn which settings to change, what values to use based on your server hardware, and how to apply them safely.
Key Takeaways: Postgres Tuning for Mastodon Performance
- shared_buffers: Set to 25% of total RAM to reduce disk reads for timeline queries.
- work_mem: Increase to 8–16 MB per operation to speed up complex filters and search.
- maintenance_work_mem: Raise to 1 GB for faster VACUUM and index rebuilds during off-peak hours.
- effective_cache_size: Set to 75% of RAM so the query planner uses indexes correctly.
Why Mastodon Needs Custom Postgres Settings
Mastodon uses PostgreSQL as its primary data store for accounts, statuses, follows, and media attachments. The official Mastodon installation guide ships with default Postgres settings that assume very little load. On a busy instance with hundreds or thousands of active users, the database becomes the bottleneck.
Mastodon generates many database queries per page load. The home timeline, for example, requires a join across statuses, follows, and reblogs. The federated timeline pulls in remote statuses and must filter out blocked domains. These queries benefit from larger memory caches and more aggressive parallelism.
The default shared_buffers value in Postgres is often 128 MB. A server with 16 GB of RAM can easily dedicate 4 GB to database caching. Without this change, Postgres reads from disk repeatedly, causing high I/O wait times and slow page rendering.
Other default settings like work_mem (4 MB) cause Mastodon’s search and filter queries to spill to temporary disk files. This adds latency. Tuning these values reduces CPU usage and improves response times for all users.
How Postgres Tuning Affects Mastodon
When Postgres has enough memory, it keeps frequently accessed data in RAM. Mastodon’s timeline queries become much faster because the database does not need to fetch data from the disk. The query planner also makes better decisions when it knows how much cache is available.
Tuning also affects background jobs. Mastodon uses Sidekiq for tasks like fan-out, media processing, and push notifications. These jobs often run database queries. A well-tuned Postgres reduces the time Sidekiq workers spend waiting for database results.
Steps to Adjust Postgres Configuration for Mastodon
- Locate the Postgres configuration file
The main configuration file ispostgresql.conf. On Ubuntu or Debian systems, it is typically at/etc/postgresql/14/main/postgresql.conf. Replace14with your Postgres version number. Usesudo nano /etc/postgresql/14/main/postgresql.confto edit it. - Set shared_buffers to 25% of total RAM
Find the lineshared_buffers = 128MBand change it. For a server with 16 GB RAM, setshared_buffers = 4GB. For 32 GB RAM, setshared_buffers = 8GB. Do not exceed 8 GB on systems with less than 8 GB of total RAM. - Raise effective_cache_size to 75% of RAM
Find#effective_cache_size = 4GB. Uncomment it and set it to 75% of your RAM. For 16 GB RAM, useeffective_cache_size = 12GB. This tells the query planner how much memory the operating system uses for file caching. - Increase work_mem for sorting and filtering
Find#work_mem = 4MB. Change it towork_mem = 16MB. This value applies per query operation. On a server with many concurrent queries, do not exceed 32 MB. Too high a value can exhaust memory under heavy load. - Set maintenance_work_mem for VACUUM operations
Find#maintenance_work_mem = 64MB. Change it tomaintenance_work_mem = 1GB. This speeds up the VACUUM process that Postgres runs automatically to reclaim storage. Mastodon instances generate many deleted statuses and reblogs, so VACUUM runs frequently. - Adjust max_worker_processes and max_parallel_workers
Find#max_worker_processes = 8. Set it to the number of CPU cores on your server. For a 4-core server, usemax_worker_processes = 4. Then setmax_parallel_workers = 4andmax_parallel_workers_per_gather = 2. This allows Postgres to use multiple cores for queries that Mastodon runs, such as federated timeline aggregation. - Restart PostgreSQL
After saving the file, restart Postgres withsudo systemctl restart postgresql. Then monitor the Mastodon logs usingjournalctl -u mastodon-web -fto confirm no errors appear.
Common Mistakes When Tuning Postgres for Mastodon
Setting shared_buffers Above 40% of RAM
When shared_buffers exceeds 40% of total RAM, Postgres competes with the operating system’s file cache. This can actually slow down queries because the OS cannot cache database files efficiently. Stick to 25% for most Mastodon instances.
Forgetting to Restart After Changes
Postgres reads configuration only at startup. If you edit postgresql.conf and do not restart the service, the changes have no effect. Always run sudo systemctl restart postgresql after modifying the file.
Ignoring Connection Limits
Mastodon uses a connection pool (typically PgBouncer) to manage database connections. If you increase Postgres’s max_connections without adjusting the pool, you may still see connection errors. Keep max_connections at 200 or lower and rely on PgBouncer for concurrency.
Not Monitoring After Changes
After applying new settings, watch the database logs and Mastodon performance. Use htop to check CPU and memory usage. If memory usage stays near 100%, reduce shared_buffers or work_mem. Use pg_stat_statements to identify slow queries.
Postgres Tuning Parameters: Default vs Recommended for Mastodon
| Parameter | Default Value | Recommended for 16 GB RAM |
|---|---|---|
| shared_buffers | 128 MB | 4 GB |
| effective_cache_size | 4 GB | 12 GB |
| work_mem | 4 MB | 16 MB |
| maintenance_work_mem | 64 MB | 1 GB |
| max_worker_processes | 8 | 4 |
Values scale with RAM size. For 32 GB RAM, double shared_buffers to 8 GB and effective_cache_size to 24 GB. Keep work_mem at 16 MB unless you have fewer than 50 concurrent connections.
You can now tune Postgres for your busy Mastodon instance using the parameters in this guide. Start by editing postgresql.conf and adjusting shared_buffers, effective_cache_size, and work_mem. Restart Postgres and monitor performance with htop and the Mastodon admin dashboard. For further optimization, enable pg_stat_statements to track the slowest queries and adjust indexes accordingly.