Splitting the Backstage backend into multiple deployments

Splitting the Backstage backend lets you run plugin groups as separate services, but it adds routing, discovery and database work that a single process avoids. This page covers when that trade-off pays off.

On this page

When one Backstage backend process is not enough

Splitting the Backstage backend makes sense when one process can no longer keep up with the work the portal asks of it, such as catalog ingestion from many sources, long scaffolder runs that tie up the process, or search indexing that competes with API traffic for the same resources. Before you split anything, confirm the bottleneck with your own metrics and traces, because a slow catalog provider, an undersized database or a missing cache often looks like a backend problem. The Backstage architecture overview describes the backend as a set of plugins that run together, and the split you make is a deployment choice, not a feature. Your users see the same portal either way, and the same plugin code runs in each process.

Each backend plugin owns its own logical database, created through Knex, so every process that hosts a plugin must reach that plugin's database. Splitting the backend therefore does not split the data. Plan the network paths and database credentials for each service before you move a plugin, and check that a plugin's tables are only written by the process that owns it. Plugins also need to find each other, which is why the routing of plugin IDs to services and the discovery configuration come next in this topic. Ask your platform team which managed or in-cluster PostgreSQL endpoints each service can use, and confirm how connection limits will be shared across the extra processes.

Ways to group plugins across deployments

Grouping by workload separates plugins according to what they do to the system: reading and ingesting catalog data, running scaffolder actions that create repositories and call external APIs, and serving search and TechDocs. Each group has a different load shape. A burst of catalog processing during a source control migration should not slow documentation reads, and a long-running template should not hold up a catalog refresh. Splitting along these lines lets you size and fail each group on its own terms.

  • Isolates resource contention: Catalog ingestion can consume CPU and database connections in bursts, so a separate process keeps interactive reads responsive.
  • Scales each group independently: Scaffolder runs and search queries have different concurrency needs, so each group can get its own replica count and timeouts.
  • Limits failure spread: A stuck action or slow external call stays inside its own process, so catalog reads can continue to work.
  • Adds shared configuration work: Every group needs consistent app-config, authentication keys and backend plugin versions, so all deployments must be built from one release.
  • Requires precise routing: Each incoming request must reach the group that owns its plugin ID, which makes the routing table a critical artifact.

Before drawing boundaries, check your monitoring data to confirm which plugins generate the most load and which group needs separate scaling.

How routing by plugin ID works in practice

Each deployment runs only the plugins assigned to it, so every request and every internal call has to reach the instance that owns the plugin it targets. In a split setup, the backend is no longer one process that answers for everything. Each group of plugins runs in its own process, and something has to decide, for each plugin ID, which base URL the caller should use. That decision lives in your configuration, not in the plugin code, so it has to be written down and reviewed like any other routing table. Start by listing every plugin your portal uses, then assign each one to exactly one group. Shared dependencies, such as the catalog that the scaffolder and search read from, are the first places where ownership questions come up, and they should be answered before any deployment is created.

The frontend and external callers reach the right service through the same routing logic, usually fronted by an ingress or reverse proxy that maps URL path prefixes to deployments. Plugin-to-plugin calls inside the backend go through the discovery layer, which resolves a plugin ID to a base URL. Confirm the current discovery and routing mechanism, the configuration keys that control base URLs and plugin groups, and how the frontend is told where each API lives, in the Backstage documentation for your exact version (see the Backstage architecture overview) rather than relying on memory. Upgrades have changed these details before, so the version you run is the reference, not an older example from a blog post.

A plugin missing from every group fails quietly at first and loudly later. If no deployment loads a plugin, its routes return errors or 404 responses, the frontend shows empty or broken pages, and any plugin that calls it fails at runtime rather than at startup. Plan a check that compares the plugin list in each group against your full inventory, and run it in CI and after each configuration change. Also test a request for each plugin route through the ingress, not only against the pod that is supposed to serve it. A routing gap is easy to miss in a portal that still loads its home page, so verify the paths your teams actually use before you call the split complete.

Configuration options and when each fits

This table compares the main layouts for the Backstage backend, from one process to split deployments with custom discovery and separate data access. Read each row for the condition that makes the option worth its operating cost, and the trade-off you accept in return. Start with a single backend and split only when a measured workload, team or sensitivity boundary justifies the extra moving parts.

DecisionWhen it fitsMain trade-off in operations or security
Single backendOne team runs the portal, load is modest, and plugins share one trust levelOne deployment to upgrade and monitor, but a heavy plugin can slow or restart every feature
Split by workloadCatalog processing, scaffolder runs or search indexing compete for CPU and memoryEach group needs its own sizing, probes and logs, and plugin routing must be tested per group
Split by teamSeparate teams own plugin groups and need independent release timingShared config and upgrades must stay in lockstep, so coordination shifts to platform engineering
Split by sensitivityScaffolder actions or integrations hold privileged credentials that should be isolated from read-only catalog APIsNetwork policy, secret scoping and audit logs must be designed per group, and cross-group calls need authentication
Default discoveryAll backend instances run in one cluster or network and can reach each other by default mechanismsSimple to start, but routing depends on the default setup, so confirm it behaves as expected once plugins run in separate processes
Custom DiscoveryServiceYour network, service mesh or DNS needs a specific way to find plugin endpoints by plugin IDYou own the discovery code and its failure modes, and it must be tested on every upgrade
Shared PostgreSQL accessOne database server with per-plugin logical databases fits your backup and operations modelShared credentials or a shared server widen the blast radius if one group is compromised
Separate PostgreSQL accessA group must be isolated for data residency, compliance scope or a different backup scheduleMore instances, credentials and backups to run, and migrations must be coordinated across them
Shared cacheSeveral instances need consistent cached results, using a shared store such as Redis or ValkeyCache availability affects every instance; see the Backstage cache page for sizing and failover

Setting up a split backend in sequence

This sequence moves plugin groups out of a single Backstage backend process one group at a time, so each move is verified before the next one starts. The result is a set of backend deployments that share one catalog and one set of configuration, with every plugin answering on exactly one instance.

  1. Inventory plugins and their dependencies

    Start by listing every backend plugin your portal loads, including the built-in ones such as the Software Catalog, Software Templates, TechDocs and search, plus the Kubernetes plugin and any custom or community plugins. For each one, record which other plugins it calls, which routes the frontend reaches it through, which database it uses and whether it runs scheduled tasks. Your engineers do this from the current backend configuration and code. The step is done when you have a written table of plugins, their callers and their resource needs, reviewed by the team that owns the portal.

  2. Choose plugin groups and their boundaries

    Group plugins by load profile and by the calls they make to each other, keeping tightly coupled plugins together so that internal calls do not cross process boundaries unnecessarily. A common starting point is to keep catalog and auth-related plugins in one group and move heavier, independently scaled plugins into their own groups. Your architects decide the grouping with the portal owners. The check is that each plugin appears in exactly one group and that the group list explains why each boundary exists.

  3. Build one image with per-group entry points

    Produce a single container image that contains all backend code, then start each group from its own entry point or configuration file so that each deployment loads only its assigned plugins. Keep the plugin list per group in configuration rather than in separate builds, so a version bump moves every group together. Your platform engineers own the build pipeline. The check is that the same image digest runs in every group and that each group's startup log lists only the plugins assigned to it.

  4. Define routing and a custom discovery service

    Configure how the frontend and other plugins find each plugin. Route incoming requests by plugin ID to the instance that hosts it, and implement a custom DiscoveryService so that internal calls between plugins resolve to the correct group. Confirm the exact interface and configuration keys against the version of Backstage you run, because discovery changes between releases. The check is a routing table that maps every plugin ID to exactly one internal address, and a test call from one group to a plugin in another group that returns a successful response.

  5. Confirm database access per plugin

    Each backend plugin uses its own logical database through Knex, so verify that every group's database credentials can reach only the databases of the plugins it hosts, and that no group needs a plugin database it does not own. Check connection settings and the PostgreSQL version your platform requires for the plugins you run. Your database administrators and the portal team do this together. The check is a connection test from each group to each of its plugin databases, and a confirmation that a group is denied access to a database that belongs to another group.

  6. Deploy a canary group first

    Deploy the smallest or least critical plugin group as a canary, send it a limited share of real traffic routed by plugin ID, and leave the rest of the plugins on the existing backend. Watch error rates, response times and logs for that group before expanding. Your platform team runs the rollout and the portal owners review results. The check is that each canary plugin answers on its assigned instance, that catalog reads and template runs that depend on it succeed, and that no request for that plugin reaches the old process.

  7. Roll out the remaining groups and retire the monolith

    Move the remaining plugin groups one at a time, running the same checks after each move: each plugin answers on its assigned instance, internal calls resolve through discovery, and database access stays limited to the owning group. Remove each plugin from the original backend only after its new group has passed these checks. Your platform team performs the moves and records the final routing table. The sequence is complete when the original backend loads no plugins and every plugin ID appears in the routing table with a passing health check.

Security and operational risks of more services

Every backend process you split off adds a service that calls other services, holds its own credentials and writes its own logs. The cards below pair each of these risks with one control to plan before the first split goes live.

Unauthenticated calls between services

Once plugin groups run as separate deployments, requests between them cross the network. Backstage backend plugins authenticate these calls with backend-to-backend tokens, so a service that accepts unsigned requests from its neighbors can be called by anything inside the cluster. Check that every group rejects calls without a valid token and that network policies limit which services can reach each other.

Credentials split across groups

Each deployment reads its own configuration, so each one needs its own copy of the secrets it uses, such as the database password, the integration tokens and the signing keys. Scope each secret to the one group that needs it. A shared secret copied everywhere turns one compromised pod into access to every plugin. Review which keys each group mounts after every configuration change.

Least-privilege database roles

Backstage gives each backend plugin its own logical database, so each split group should connect with a role that can reach only its own databases. Do not let one role own all of them, because a single leaked connection string would then expose the catalog, scaffolder history and search index together. Ask your database team to confirm that grants match the plugin-to-group mapping before go-live.

Audit logging per instance

Each backend instance writes its own logs, so a sign-in or scaffolder action can appear in one group's logs and not in another's. Aggregate logs from every instance into one store with the instance name attached before you rely on them for investigations. Confirm that the audit events you need are emitted by the group that handles them and that retention covers your incident response window.

Identical sign-in resolvers everywhere

The authentication documentation advises configuring sign-in resolvers so every provider resolves to the same identity. If the backend instances that handle sign-in do not share identical resolver configuration, one user can map to different catalog identities depending on which instance answers. Keep the auth configuration in one source of truth and deploy it to every instance with the same version.

Config drift across releases

Split deployments must run the same Backstage package versions, or plugins built against different releases can disagree on internal APIs. Upgrade all groups in one planned change window and record which version each group runs. Compare configuration files for each group during every release so a setting missing from one deployment does not surface as an outage.

Why multi-region copies make sense only for single plugins

Running full Backstage backend copies in several regions is rarely the right answer, because every copy carries its own process, its own plugin databases, its own cache and its own upgrade window. Each backend instance must run the same @backstage package versions, so a regional rollout turns one upgrade into several coordinated ones. The better default is to keep one primary backend and replicate only a single plugin that is read-heavy or sensitive to latency, such as a search or catalog read path that regional users hit constantly. Before you split anything, measure where your users and callers actually sit and which plugin requests dominate that traffic.

Data residency decides more than latency does. Each backend plugin gets its own logical database in PostgreSQL, so you need to know which region holds the catalog, scaffolder task history, search index and auth tables before you place a copy. If a regulation or internal policy requires certain records to stay in one jurisdiction, a regional replica of a plugin that writes personal data may be impossible to justify, while a replica that serves only public catalog metadata may be acceptable. Ask your privacy and legal owners to classify each plugin's data, and confirm with the Backstage architecture overview how each plugin stores its state before you design any replica.

The right split depends on your latency and residency requirements, and you should test it in your own environment rather than assume it. Build a small pilot with one plugin replicated to a second region, point a representative set of users at it, and measure response times, cache hit behavior and failure modes when the primary region is unreachable. Record how long a version bump takes across both copies and who owns the rollback. If the pilot does not show a clear gain for a single plugin, keep one deployment and spend the effort on caching and database sizing instead.

Limits to confirm in your environment

A split Backstage topology depends on details that change between releases and between plugins. The cards below list what to verify before you commit to a layout, who can answer each question, and how to test it in a staging copy that mirrors production routing.

Plugin support for split deployment

Not every backend plugin is designed to run as a separate process behind a routed endpoint. Confirm for each plugin in your build whether its documentation or maintainer describes running it in a split topology, and which plugin IDs must be routed to which group. Check this against the exact @backstage version you run, since plugin behavior can change between releases. Where the answer is unclear, ask the maintainer and record the answer in your design document.

Cache behavior across instances

If several instances share cached data, a plugin that assumes a single process may serve stale results or invalidate entries unevenly. Confirm which caches are shared through your configured cache store and which stay in process memory on each instance. Test a catalog change followed by a read from a different instance to see whether the change appears within the timing you expect. Ask the plugin maintainer whether cache keys include the plugin ID.

Scheduler and catalog processing ownership

Scheduled tasks such as catalog refreshes and entity providers can run on every instance that hosts them, which may duplicate work or create conflicting writes. Decide which group owns each scheduled task and confirm that the task framework coordinates runs across instances. Check the catalog processing documentation and your own logs for duplicate refresh events after a rollout. Document the owner of each scheduler job so an on-call engineer knows where to look.

Upgrade coordination across groups

Every backend group must run compatible @backstage packages, so a version bump has to move all groups together. Plan a release order, confirm that the Upgrade Helper shows template changes that affect your configuration, and test mixed-version traffic during rollout. Ask your platform team how long a split-version window can last before a plugin fails on schema or API changes.

Node.js compatibility under the policy

Each group runs on the same Node.js runtime as your build, so the runtime must match the versions Backstage supports for your release. Confirm the supported Node.js lines in the versioning policy for your Backstage version, then verify that your base image and any custom plugin dependencies build against them. Recheck this before each Node.js change, because a group that falls behind can break only at deploy time.

Authentication and identity consistency

Each split group receives requests that must resolve to the same identity, so sign-in resolvers and shared secrets must match across groups. Confirm that every group validates the same tokens and uses the same resolver output, and test a user session that crosses groups. Ask your identity team to verify that guest access is disabled in every group before production traffic reaches it.

Questions teams ask before splitting the backend

What drives the cost of splitting a Backstage backend into several deployments?

The main drivers are the number of plugins you plan to move out of the main process, how many of them are custom, and how much routing and service discovery work the split requires. Each separate deployment adds its own configuration, health checks, database access, secrets and monitoring, and each custom plugin needs tests that prove it still works when called from another process. Cost is mostly one-time design and build work, plus a recurring share for running the extra services. Ask any partner to price these items separately in the written scope: plugin inventory, routing and discovery design, custom DiscoveryService work, test coverage, rollout and documentation.

How long does it take to split the Backstage backend?

Duration depends on the same factors as cost: how many plugins move, whether any are custom, and how many environments need the change. A small split with a few built-in plugins is far shorter than a split that includes custom plugins, a bespoke discovery layer and staged rollout across environments. No fixed duration applies to every portal, so ask for a timeline in the written scope that lists each phase, the environments it covers and the acceptance tests. Your own team should also plan time for a parallel run, where the single-process and split setups both work until the split is verified.

What does the work need from our platform and identity teams?

The split needs decisions and access from several owners before engineering starts. Platform owners must agree on how each deployment is packaged, scaled and exposed to the others, and whether they run it on Kubernetes or another platform you control. Database owners must grant access so each plugin keeps its own logical database in PostgreSQL. Identity owners must confirm how callers authenticate to each service, because sign-in resolvers and service-to-service trust follow the same identity model. Name a decision owner for each of these areas before the work is scoped.

Can our internal team split the Backstage backend without a partner?

Yes, if your team already runs Backstage in production, understands its plugin system and has someone comfortable with service discovery and database configuration. The work is engineering rather than specialist tooling, so the question is capacity and risk tolerance. Teams with no prior production Backstage experience usually find the custom DiscoveryService, the routing by plugin ID and the testing of cross-process calls the hardest parts. A partner can carry the design and build while your staff learn the setup, and you can ask for that knowledge transfer to be written into the scope.

How does upgrading Backstage change when there are several deployments?

Every deployment must run the same set of @backstage package versions, because the split does not change how Backstage releases work. Use the documented upgrade path, which moves all @backstage packages together with yarn backstage-cli versions:bump, and check template changes in the Backstage Upgrade Helper before each bump. Each service then needs its own build, rollout and smoke test, so an upgrade takes longer and has more points of failure. Plan a rollout order, confirm that the routing layer handles mixed versions during the window, and test the upgrade in a non-production environment first.

Do we need multi-region copies of the whole Backstage backend?

Usually not. Running full copies of the backend in several regions multiplies the operational load without solving the problem most teams have. Multi-region copies make sense for a single plugin with a clear latency or availability need, and the design should show which plugin, which users and which failure you are addressing. Ask your partner or internal team to justify each regional copy in writing, and to state how the database, the cache and the catalog data stay consistent across regions.

What goes wrong most often when the backend is split?

The most common problems are plugins that cannot find each other after routing changes, service calls that bypass the authentication you expected, and database connections that point at the wrong plugin schema. Configuration drift between deployments is another frequent cause of failure, especially when one service runs an older configuration file. Require a test plan that checks routing by plugin ID, cross-process calls, authentication on every exposed route and a rollback procedure for each deployment before the first production change.

How DeployOpen scopes and delivers a split Backstage backend

DeployOpen plans, builds, documents and supports self-hosted open-source platforms inside your own infrastructure, and a split Backstage backend is handled the same way. We start from the plugins you run, the load and failure domains they create, and the routing and discovery decisions that follow from them.

How we scope

  • Inventory every backend plugin and group them by ownership, load profile and failure impact before any split is proposed.
  • Confirm which routes each deployment serves, how requests reach them by plugin ID, and which plugins stay in the main process.
  • Agree the written scope, deliverables and timeline in writing before work starts, since most engagements are fixed-scope.

How we build

  • Configure the backend deployments with shared PostgreSQL, a shared cache and a custom DiscoveryService matched to your network layout.
  • Test internal authentication between deployments and confirm external callers reach only the routes they are meant to reach.
  • Verify catalog ingestion, scaffolder runs and search results after each change, and record the results for your review.

How we hand over

  • Deliver the deployment manifests, routing configuration, discovery code and a runbook that explains each deployment's role.
  • Document the decision record for each split, including why a plugin was or was not separated and what would trigger a rethink.
  • Walk your platform and security engineers through rollback steps, health checks and how to add a new plugin to the layout.

How we support

  • Ongoing support, upgrades and continuous testing are available as retainers after handover.
  • Plan upgrades that move all @backstage packages together so every split deployment stays on the same release line.
  • Review new plugin additions and routing changes against the split design before they reach production.

Talk to our team.

Tell us what you're working on, whether it's a deployment, an audit, a security test or a cyber range. You'll speak with an engineer who can help you scope it.

  • 30-minute call: free, with no obligation.
  • NDA on request: we can sign before you share details.
  • Clear next steps: a scope and plan after the call.