Hardware FixRecommendedDevice not working? Your driver may be the problemCheck updates for common hardware issues.Fix DriversOctober DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsClean PCRecommendedOne scan can reveal what keeps slowing WindowsLook for cleanup and repair opportunities.Run Scan×
Skip to content
World desk12 min

How to Scale Your Mastodon Server: A Practical Architecture and Capacity Guide

Scale Mastodon safely by measuring each tier first, then tuning Puma, streaming, Sidekiq, PostgreSQL, Redis and media storage independently. This guide includes connection budgeting, health checks, object-storage design and failure recovery.
Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Scale Mastodon by finding the saturated tier, then adding capacity only there: Puma handles short HTTP requests, the streaming API handles long-lived connections, and Sidekiq runs background jobs. More workers and nodes also consume PostgreSQL connections, Redis memory and network bandwidth, so measure queue latency, database connections, streaming channels, CPU, RAM and media growth before changing the architecture. There is no official users-per-server formula; your measurements, workload mix and failure objectives determine the right design.

What “scaling Mastodon” actually involves

A Mastodon instance is not one interchangeable application process. The official Mastodon documentation describes three process types:

As an Amazon Associate I earn from qualifying purchases.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
  • Web (Puma): short-lived HTTP requests such as timelines, settings pages and API calls.
  • Streaming API: long-lived HTTP or WebSocket connections that deliver live timeline updates.
  • Background processing (Sidekiq): asynchronous work, including federation delivery, incoming activities and email.

PostgreSQL, Redis and media storage are shared dependencies beneath those tiers. Increasing concurrency in one tier can therefore move the bottleneck to a dependency. A successful scale-up keeps headroom in every layer and makes failure behavior predictable.

Mastodon’s official guides do not publish a universal CPU, RAM, disk or user-count recommendation. Two instances with the same registered-user count can have very different loads because of active-user ratio, federation volume, timeline behavior, streaming connections, media retention and moderation activity. Treat capacity as an observed property of your workload, not a number inferred from account count.

Measure the bottleneck before adding servers

Take a baseline during normal traffic and during your busiest periods. Record enough history to distinguish a short spike from a persistent limit. A load balancer can hide an unhealthy streaming node, so collect metrics from every instance as well as from the shared services.

Layer What to measure What a warning usually means
Puma/web Request latency by endpoint, error rate, CPU saturation, memory use and worker utilization HTTP work is waiting for a worker, CPU or memory; inspect Puma settings and application dependencies before adding nodes.
Streaming Connected channels, messages sent, Redis messages received, connection errors and per-node CPU/RAM Long-lived connections or fan-out are concentrating on one node; add streaming instances or fix the unhealthy backend.
Sidekiq Queue depth and latency, job failures, retry volume and concurrency by queue Background work is falling behind; identify the queue and its database-connection cost instead of raising all concurrency.
PostgreSQL Active and idle connections, wait events, query latency, CPU, RAM, storage latency and replication lag More application concurrency may exhaust the connection budget or make the database the limiting resource.
Redis Memory, evictions, command latency, blocked clients, throughput and failover events Feeds, queues, streaming messages or cache traffic are competing for one instance’s resources.
Media storage Disk or object-storage growth, request latency, failed uploads and cache-retention volume Media is tying capacity to one host or retention is growing faster than expected.

Use queue latency rather than queue length alone: a small queue containing slow jobs can be more urgent than a large queue of quick jobs. Likewise, count active streaming channels and message rates, not only CPU percentage. Keep per-instance dashboards so a round-robin load balancer cannot conceal one degraded backend.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Separate the three application tiers

Run Puma, streaming and Sidekiq as independently tunable services. This lets you add capacity to the tier that is actually constrained instead of multiplying every process and consuming database connections unnecessarily.

Tier Work pattern Scale primarily by Important dependency
Puma Short HTTP requests More worker processes, additional web nodes or both PostgreSQL connections, CPU and RAM
Streaming API Long-lived HTTP/WebSocket connections and fan-out Additional streaming instances behind a load balancer Redis traffic and PostgreSQL connections
Sidekiq Federation, ingress, email and other asynchronous jobs Queue-specific concurrency and additional workers PostgreSQL connections and queue priority

Keep each service’s process supervision, logs and health checks separate. A web node that is healthy for ordinary HTTP traffic is not automatically healthy for streaming, and a fast web response does not prove that federation queues are keeping up.

Tune Puma without exhausting the host

Understand the two controls

WEB_CONCURRENCY controls Puma worker processes. MAX_THREADS controls threads per worker. The configuration documentation lists documented defaults of WEB_CONCURRENCY=2 and MAX_THREADS=5; these are version-sensitive defaults, so confirm the values for the Mastodon release you run.

More processes generally improve throughput until memory becomes the limit. More threads tend to exhaust CPU first. Each change also increases potential database demand. Increase one setting at a time, observe latency and connection use, and keep a rollback value.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

A safe tuning sequence

  1. Record current request latency, error rate, CPU, RAM and PostgreSQL connections.
  2. Increase worker processes modestly when requests are waiting and the host has memory headroom. Watch resident memory after the change, not just startup usage.
  3. Change thread count only when CPU and database measurements show that additional concurrent request work is useful. If CPU pegs or database waits rise, revert rather than adding threads indefinitely.
  4. Repeat the measurement during your peak period. A setting that looks efficient at quiet times can overload PostgreSQL during a federation burst.

When one web node remains saturated after sensible tuning, add another Puma node instead of making a single machine ever larger. Put all web nodes behind a health-checked load balancer and include their combined connection demand in the PostgreSQL budget.

Add streaming capacity horizontally

The current configuration documentation describes the streaming server as a single Node.js process per instance and directs further scaling to the scaling guide. The older STREAMING_CLUSTER_NUM setting has been removed; do not build a current deployment around it.

  1. Run an additional streaming instance using the same application configuration and shared Redis namespace.
  2. Place streaming instances behind a proxy or load balancer that supports long-lived HTTP/WebSocket connections and has suitable idle timeouts.
  3. Health-check each backend directly and monitor connected channels, messages sent, Redis messages received, errors and CPU/RAM per node.
  4. Add instances when channel counts or message fan-out saturate a node, then verify that traffic is distributed rather than simply duplicating an unhealthy configuration.

Every streaming instance can consume PostgreSQL connections. Include the streaming fleet when calculating the connection budget, even though its principal workload is persistent connections and Redis messaging.

Scale Sidekiq by queue, not by guesswork

Sidekiq concurrency determines how quickly Mastodon processes jobs such as federation delivery and email. The key constraint is that each Sidekiq thread requires a PostgreSQL connection. Set DB_POOL to at least the Sidekiq thread count for that process, then account for Puma and streaming connections as well.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Preserve queue priority

  • default: work affecting local users.
  • push: delivery to other servers.
  • ingress: incoming remote activities, processed at lower priority than local-user work.

If push latency grows while local timelines remain responsive, add capacity to delivery workers rather than globally increasing every queue. If ingress backlog grows, verify that incoming activity processing is not starved by retries or a database bottleneck. Keep queue priority intentional: allowing low-priority work to consume all threads can make the instance feel broken to local users.

A queue-focused procedure

  1. Identify the queue with the highest age and failure rate.
  2. Check whether its jobs are CPU-heavy, network-bound or database-bound.
  3. Increase concurrency for that queue in a small step while watching PostgreSQL connections and query latency.
  4. Raise DB_POOL only when the database and connection budget can support the added threads.
  5. Stop or roll back when connection waits, database latency or host CPU becomes the new bottleneck.

Protect PostgreSQL as concurrency grows

Budget connections explicitly

Mastodon’s scaling guide cites PostgreSQL’s default limit as 100 connections. Treat that as a limit to plan around, not as available application capacity. Add the possible connections from every Puma worker and thread, each Sidekiq thread, streaming instances, administrative sessions, migrations and monitoring. Leave safety margin for failover and maintenance.

Adding workers without this accounting can replace slow requests with connection errors. A database that reports many idle sessions may still be unable to accept a sudden concurrency increase if the configured maximum is reached.

Use PgBouncer when the connection budget is the limit

When combined demand approaches PostgreSQL’s limit, Mastodon documents PgBouncer transaction pooling as the next step. Transaction pooling reuses a smaller number of database connections across many short transactions. It requires prepared statements to be disabled; the configuration guide notes that the pooling benefit can outweigh prepared-statement advantages at scale.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Size the pool from measured concurrent database work, not from the number of application threads. Test transaction boundaries, migrations, long-running queries and administrative tools before making PgBouncer the only path to the database. Keep direct administrative access available for incidents.

Consider read replicas in supported releases

Mastodon 4.2 and later include built-in read-replica support through REPLICA_DB_* or REPLICA_DATABASE_URL. The application pauses replica reads when lag exceeds a few seconds. Replicas can reduce read pressure, but they do not remove the need to size the primary for writes, Sidekiq work and consistency-sensitive operations. Monitor lag and confirm which queries are eligible for replica routing before relying on the capacity.

Separate Redis workloads and plan failover

Redis carries home feeds, list feeds, Sidekiq queues, streaming communication and cache workloads. A single overloaded Redis instance can therefore slow apparently unrelated features.

Split roles when measurements justify it

Configure a separate cache Redis with CACHE_REDIS_* and/or a dedicated Sidekiq Redis with SIDEKIQ_REDIS_*. Separating cache eviction or Sidekiq bursts from feed and streaming traffic limits blast radius. It also makes memory alerts meaningful: cache pressure should not silently evict queue data.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Use Sentinel for monitored failover

Redis Sentinel can monitor masters and direct clients to a new primary after failure. Set timeout and failover behavior to match your availability target, then test it under load. A failover that works in a quiet test may still produce unacceptable queue delay or reconnect storms during a federation spike. Document the expected promotion time and verify that every Mastodon process can discover the new primary.

Move media to shared object storage

Mastodon’s object-storage documentation says user-uploaded files can reside on the main server’s filesystem or on an external object-storage server, and that external storage can be required for scaling. Shared S3-compatible storage gives multiple application nodes one media namespace and prevents uploads from filling one host’s disk.

When external storage becomes necessary

  • You are adding web or worker nodes and cannot keep identical local media on every node.
  • Media growth is consuming the operating system or database host’s disk.
  • You need to replace application nodes without copying a large media tree first.
  • You want a storage layer that can be backed up independently of compute nodes.

Plan object-storage capacity, request latency, access credentials, lifecycle policy and egress costs. Test uploads, downloads, avatar changes, remote-media fetches and deletion behavior before cutting over. Keep the bucket and application configuration consistent across every node.

The backup guide names Amazon S3, Google Cloud and Wasabi as examples where locally backing up uploaded files is unnecessary. “Unnecessary” does not mean “unprotected”: verify provider durability, versioning or retention requirements, access controls and a recovery procedure that can restore media references and objects together.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Put web and streaming nodes behind health-checked load balancing

Multiple web and streaming nodes should sit behind a load balancer that removes failed backends automatically. The scaling guide lists DigitalOcean, AWS and Hetzner as examples of providers offering virtual load balancing; the design principles are provider-independent.

Backend Health-check path Expected response
Web/Puma /health HTTP 200 with OK
Streaming /api/v1/streaming/health HTTP 200 with OK

Use checks that run from the load balancer’s network location and set timeouts appropriate for the endpoint. Confirm that a failed check drains connections as intended, that a recovered node is reintroduced only after it is ready, and that WebSocket or streaming idle-timeout settings do not terminate healthy clients.

Monitor each backend directly. Aggregate load-balancer statistics are useful for traffic distribution, but they cannot tell you which streaming node is accumulating channels or errors.

Control media-cache and archive retention

Media and user archives are capacity variables, not one-time setup details. Mastodon administration settings include media-cache retention and user-archive retention. The cleanup task runs through the background scheduler, so retention policy depends on healthy background processing.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
  1. Choose retention periods that match moderation, legal and user-support requirements.
  2. Estimate the resulting storage growth from observed daily media and archive creation.
  3. Confirm that scheduled cleanup jobs are completing and not accumulating in Sidekiq.
  4. Alert when disk or object-storage growth diverges from the policy you selected.

Reducing retention can lower storage growth, but it does not repair a Sidekiq backlog or immediately reclaim every byte. Schedule changes and observe the cleanup queue before assuming capacity has been recovered.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Architecture patterns by bottleneck

Observed constraint First architectural response What to verify before expanding
HTTP latency with spare database and memory headroom Tune Puma, then add another web node behind the load balancer Worker memory, CPU saturation and combined PostgreSQL connections
Streaming channels or fan-out saturate one node Add streaming instances and monitor each instance directly WebSocket proxy settings, Redis throughput and connection budget
Delivery or ingress queue age rises Add queue-specific Sidekiq capacity while preserving priority Per-thread database connections, retries and database latency
PostgreSQL reaches its connection limit Reduce unnecessary concurrency and add PgBouncer transaction pooling Prepared-statement compatibility, pool sizing and query waits
Redis memory or latency is high Separate cache and/or Sidekiq Redis; evaluate Sentinel Evictions, queue durability and failover behavior
Media disk grows or nodes need a shared namespace Move uploads to S3-compatible object storage Upload/download tests, lifecycle rules and recovery

This is a decision framework, not a hardware prescription. The official documentation does not establish a universal cost or machine-size table. Compare alternatives by the bottleneck they address, connection and queue headroom, failure recovery, operational complexity, recurring cost and data portability.

A staged scale-out runbook

  1. Instrument: establish dashboards for Puma latency, Sidekiq queue age and failures, PostgreSQL connections and lag, Redis memory and latency, streaming channels and media growth.
  2. Document limits: record PostgreSQL connection maximum, current process counts, thread counts, DB_POOL values, Redis memory limits and storage-retention policies.
  3. Fix the narrow bottleneck: tune the affected tier or dependency without changing unrelated tiers.
  4. Re-test under peak conditions: compare latency, queue age, errors and resource headroom before and after the change.
  5. Make shared state external: move media to shared object storage before adding nodes that would otherwise have divergent local files.
  6. Add redundancy: place web and streaming nodes behind health checks; separate Redis roles where contention is demonstrated; test database and Redis recovery.
  7. Write rollback steps: keep prior environment values, drain procedures, database access and restore instructions available before each production change.

Common failure modes and recovery

“More workers made the site slower”

Check PostgreSQL connections and wait events first. More Puma or Sidekiq concurrency can create contention, connection exhaustion or CPU pressure. Roll back the last increase, then use PgBouncer or a database-focused change only after confirming the connection limit is the constraint.

“Streaming works through the load balancer, but one node fails”

Inspect per-node channels, Redis messages received, errors and health-check results. Verify the streaming health path and WebSocket timeout settings. Remove the unhealthy backend, correct its configuration or resource limit, and reintroduce it only after a direct health check succeeds.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

“Federation queues never catch up”

Separate push, ingress and default queue age and failure data. Check retries, remote-network errors and database latency. Add concurrency to the affected queue only when its connection pool and PostgreSQL headroom support it.

“A Redis restart causes several symptoms at once”

Determine whether cache, Sidekiq and streaming traffic share the instance. Separate roles where contention is recurring, configure Sentinel if automatic primary discovery is required, and test client reconnect behavior rather than assuming failover is transparent.

“A new application node cannot see uploaded files”

Local media directories are node-local. Move to shared S3-compatible storage or provide a deliberately synchronized filesystem, then test reads and writes from every node. Object storage is usually the cleaner scale-out boundary because it avoids keeping large media trees identical on each host.

“Disk keeps filling after reducing retention”

Check that the scheduled cleanup jobs are running and completing. Retention settings do not help while Sidekiq is stalled, and reclamation may lag behind the policy change. Monitor both the cleanup queue and actual disk or bucket usage.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

How to judge whether the new design is ready

  • Each tier has a measured bottleneck and a documented scaling control.
  • Combined Puma, Sidekiq and streaming connection demand remains below the database limit with failover headroom.
  • Queue priority is preserved and the oldest important queue remains within your service objective.
  • Every web and streaming backend has a direct health check and per-node monitoring.
  • Redis memory, latency and failover behavior have been tested for the expected workload.
  • Media is reachable from every application node and can be restored independently of compute hosts.
  • Retention cleanup is scheduled, observable and included in storage forecasts.
  • Rollback, node replacement and database-recovery procedures have been rehearsed.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Leave a Reply

Your email address will not be published. Required fields are marked *

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

More from the Wire

  1. World desk4 min
    How to Spot an AI Voice Scam Before Sending MoneyDon’t rely on how a caller sounds. Pause, call back through a known number, and verify the emergency with another trusted person before sending money.
  2. Mountain View desk4 min
    Google’s SynthID Detector: How to Check AI-Generated Images, Video and AudioGoogle’s SynthID Detector looks for an embedded watermark in supported images, video and audio. Here is what its results do—and do not—show.
  3. Redmond desk20 min
    How to create a link to File or Folder in Windows 11Windows 11 gives you several ways to point to a file or folder without moving or duplicating it. You can create a desktop shortcut,…
Recommended PC Tool
Recommended PC Tool
PC Slower Than It Used to Be?Free scan - under a minute
Crashes, No Sound, or Screen Glitches?Free driver scan

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.