Every platform engineering conference talk ends the same way: with an org chart. A platform product manager, two or three platform engineers, maybe an SRE, all building an internal developer platform so the rest of engineering can ship faster. It is a compelling picture, and at a company with three hundred engineers it is probably the right one. At your company, it is a picture of two to four salaries you would have to pull out of product engineering to fund a team whose product is internal. Meanwhile, the actual problem sits in your Slack right now: one ops person, every deploy queued behind them, and a growing pile of "can you push this to staging" messages that each cost twenty minutes of context switching.
Here is the argument of this post: the outcomes an internal developer platform delivers, developers who ship without filing tickets and a delivery path that is the same for every app, do not require platform-team headcount at your size. A manifest-driven platform gets you those outcomes with the ops person you already have, running in the AWS account you already pay for. The salary line a platform team would consume stays in product engineering, where it ships features customers pay for. What follows is the concrete version of that argument: what an IDP actually is, what parts of it matter at 10 to 30 engineers, and a one-quarter plan your current ops person can execute.
Strip away the vendor landscape diagrams and an internal developer platform is defined by four outcomes, not by any particular architecture:
Notice what is not on that list: a service catalog portal, a custom CLI your team wrote, a Kubernetes cluster your team operates by hand, or Backstage. Those are implementations, and they are the expensive part. Large organizations build them because their scale and internal complexity justify it. The mistake mid-size companies make is copying the implementation when what they needed was the outcomes. If a developer at your company can go from merged code to running release without your ops person in the loop, and every service follows the same path, you have an internal developer platform. The question is only whether you built it with headcount or bought it as a product.
At your size, the four outcomes above rank very differently than they do at enterprise scale. Self-service is worth the most, because your constraint is a single person's queue. Every deploy that flows through your ops person is a context switch for them and a wait for the developer, and both costs compound as the team grows. If you are opening your first or second DevOps requisition right now, that req is usually a proxy for this exact bottleneck: the job description says "build CI/CD and infrastructure automation" and the underlying need is "make deploys stop routing through one calendar".
Standardization is worth the second most, and it is the quiet one. Ten services deployed ten slightly different ways means ten things only one person understands, which is how you end up with an ops person who cannot take a vacation. One manifest format across every service means the newest engineer on the team can deploy any of them, and the ops person's knowledge stops being a single point of failure.
Guardrails and visibility matter, but at this size they should come as defaults, not as projects. You do not have the capacity to build an approval workflow engine or a custom audit pipeline, and you should not need to. A platform that ships automatic rollback on failed health checks and an audit trail out of the box gives you the guardrail outcome without a guardrail project. What a bespoke platform team would spend a quarter building, you want to get by setting a parameter.
This is where Convox Rack fits. A Rack is a complete delivery platform that installs into your own AWS account: the Kubernetes cluster, the build system, the load balancing, the TLS certificates, the log aggregation, and the deploy workflow, all provisioned and updated as one unit. Your applications are described declaratively in a manifest, and developers interact with the platform through a small CLI surface: convox deploy, convox logs, convox env set, convox releases rollback. The Kubernetes underneath is standard, so you are not locked into a proprietary runtime, but nobody on your team has to operate it directly.
The division of labor is the point. Developers get the self-service loop. Your ops person gets the control plane: they own the Rack, its parameters (instance types, networking, scaling schedules), and the AWS account itself. That framing matters if your ops person built your current stack by hand: this is not a replacement for their work, it is a multiplier on it. Their AWS knowledge still governs the account, the VPC, the IAM boundaries, and the cost levers like reserved instances. What they stop doing is being personally present for every deploy. We have made the longer version of this argument in platform engineering without a platform team; the short version is that at 10 to 30 engineers, the platform team's entire job description can be a product plus the one person you already employ.
Because the Rack runs in your own AWS account, the infrastructure bill is your existing AWS relationship. Convox adds no markup on that infrastructure; you pay AWS directly, at whatever negotiated rates and savings plans you already have.
Platform teams talk about the "golden path": the paved road every service follows, so nobody hand-builds delivery per app. In Convox, the golden path is a file. convox.yml lives in each repository and declares everything the platform needs to run the app: the services and their scale, the databases and caches they depend on, and any scheduled jobs. Here is a realistic one for a web app with a background worker, a Postgres database, and a nightly cleanup job:
environment:
- RAILS_ENV=production
- SECRET_KEY_BASE
resources:
database:
type: postgres
services:
web:
build: .
command: bin/web
port: 3000
health: /health
scale:
count: 2
cpu: 250
memory: 512
resources:
- database
worker:
build: .
command: bin/worker
resources:
- database
timers:
cleanup:
schedule: "0 3 * * *"
command: bin/cleanup
service: worker
Walk through what this replaces. The resources block declares a Postgres database; the platform provisions it and injects the connection string as DATABASE_URL into every linked service, so nobody hand-wires credentials (see Resources). The timers block is your cron infrastructure: a standard cron expression, a command, and the service whose image runs it. The health path is the contract the platform uses to decide whether a new release is safe to receive traffic. Secrets are never in the file; the manifest declares that SECRET_KEY_BASE must exist, and its value is set out of band with convox env set.
Because every app on the Rack uses this same format, the manifest is also your standardization mechanism. A developer who has deployed one service can read and deploy all of them. Compare the surface area against operating the equivalent Kubernetes directly:
| Concern | Self-managed Kubernetes | Convox Rack |
|---|---|---|
| HTTPS routing | Ingress controller, cert-manager, DNS wiring per service | port: 3000 in convox.yml |
| Database | Provision RDS, manage secrets, wire env vars per environment | type: postgres plus a link |
| Cron jobs | CronJob manifests, image references, RBAC | A timers: entry |
| Safe rollout | Deployment strategy tuning, probe configuration, rollback runbooks | Default rolling updates with automatic rollback |
Here is the loop your developers run, with the ops person nowhere in it. The developer deploys:
$ convox deploy -a myapp
Packaging source... OK
Starting build... OK
Build: BABCDEFGHI
Release: RBCDEFGHIJ
Promoting RBCDEFGHIJ...
The promotion is a rolling update: the platform starts one new process, waits for it to pass its health check, stops one old process, and repeats. During this the app's status moves from running to updating. If the new release fails its health checks, the app enters rollback status and the platform reverts to the previous release on its own; the bad deploy never fully replaces the good one (see app statuses). If the developer simply shipped the wrong thing, they revert themselves with convox releases rollback, which promotes a copy of a known-good release. Configuration changes follow the same pattern: convox env set FEATURE_FLAG=true --promote creates and promotes a new release, and convox logs streams output when something looks off. Nobody messaged the ops person at any point in that paragraph.
Self-service without boundaries is how developers end up with production AWS credentials, which is the failure mode your ops person rightly fears. The Rack draws the line cleanly. Developers operate apps; they do not touch the account. The ops person sets rack parameters like node types and network topology with convox rack params set, and those decisions are invisible to app deploys. Role-based access control separates read-write app operations from Admin-only actions, so sensitive operations like changing budget caps require the Admin role even when everyday deploys do not. CI systems authenticate with deploy keys, which are scoped to a restricted command set rather than to a person's credentials. And because everything runs in your AWS account, your existing IAM boundaries, billing alerts, and security tooling all still apply. The developers got leverage; the account did not get more people in it.
Honesty about the boundary makes the rest of this post more useful. A bought platform is opinionated, and the opinion is the value: one manifest, one deploy path, one rollback model. That means there are things it will not do. If you need bespoke workflow orchestration across dozens of teams, a custom internal service catalog with organization-specific metadata, or arbitrary internal tooling stitched into the delivery path, a product will not bend that far, and building with a dedicated team becomes rational. The signals that you are approaching that line are reasonably concrete: multiple product lines with genuinely different delivery requirements, platform requests arriving faster than one person can triage even with a product doing the heavy lifting, or two-plus engineers already spending most of their time on internal infrastructure regardless of what you call them. At that point a platform team is not overhead, it is the org catching up to reality.
Below that line, the arithmetic favors buying, and you can redo it yourself. A platform team is a multiple of a senior engineer's fully loaded cost per year in your market; take whatever number your last senior hire cost you and multiply by two or three. A Convox Rack is a platform subscription plus your AWS bill, which you were paying anyway and which carries no Convox markup on a self-hosted Rack. The build path also carries a cost the spreadsheet misses: the platform your team builds is version one of an internal product that now needs maintenance forever, and the engineers who built it become the new single point of failure. You would be trading one bottleneck for a more expensive one.
The trade-off in the other direction is real too, so name it: adopting a manifest-driven platform means converting each app to a Dockerfile and a convox.yml, and it means accepting the platform's opinions instead of preserving every bespoke choice in your current setup. If your ops person has hand-built automation they are proud of, some of it will be superseded, and the right way to frame that is as capacity returned to them, not work discarded. The conversion cost is front-loaded and finite; the bottleneck cost is recurring and grows with headcount.
This does not need a migration program. It needs one quarter and the ops person you have.
| Month | Focus | Done looks like |
|---|---|---|
| One | Install a Rack in your AWS account and move one real app onto it: write its convox.yml, deploy, and validate on the Rack-assigned hostname before touching DNS | One app serving traffic from the Rack; ops person comfortable with rack parameters |
| Two | Standardize: convert the remaining services to the same manifest pattern, moving cron jobs to timers and databases to linked resources | Every service deployable the same way; no snowflake pipelines left |
| Three | Hand deploys fully to developers, set roles and deploy keys, and start measuring | Zero routine deploys through the ops person; you track deploy frequency and ops interruptions yourself |
The measurement in month three is deliberately yours, not ours: count deploys per week and count the times a developer had to pull the ops person into a delivery task, before and after. Those two numbers are the business case for the whole exercise, in units your CEO already understands. If they do not move, you learned that cheaply in one quarter. If they do, you got the internal developer platform outcome without the internal developer platform org chart.
An internal developer platform is the layer that lets developers deploy, configure, and operate their applications through self-service instead of tickets, with a standard delivery path and guardrails built in. It is defined by those outcomes, not by any specific tool; it can be built by a dedicated team or bought as a product like a Convox Rack.
No. Platform engineering is the discipline and usually the team; the internal developer platform is the thing developers actually use. Large organizations staff a platform engineering team to build and run their IDP. Smaller companies can get the same platform outcomes from a product operated by one ops person, without funding the discipline as a headcount line.
No. Backstage is a service catalog and portal framework, and it requires ongoing engineering effort to run and customize. A catalog is useful at large scale, but the core IDP outcomes are self-service deploys, a standard path, and guardrails. A manifest-driven platform delivers those directly, and a portal can be added later if the need appears.
There is no fixed number, but the signals are consistent: multiple product lines with genuinely different delivery needs, platform work exceeding what one person plus a product can absorb, or two or more engineers already working full time on internal infrastructure. Below those signals, typically the case from 10 to 30 engineers, buying the platform keeps salaries in product work.
Yes, when the platform is a managed product rather than a hand-built stack. On a Convox Rack the ops person owns rack parameters, roles, and the AWS account, while developers self-serve deploys, environment changes, logs, and rollbacks. Automatic rollback on failed health checks handles the riskiest moment without anyone being paged into it.
Here is the decision-shaped version of everything above. Ask your ops person for their top three recurring ticket types. Check each one against this post: deploys, environment changes, log access, and rollbacks are all eliminated by the self-service loop, and cron and database provisioning are eliminated by the manifest. If two of the three are on that list, stand up a Rack with one app this month as the pilot, then run the quarter plan. The Getting Started Guide covers installation through first deploy, and the pricing page gives you the number to put next to the headcount alternative.
Create a free account and install your first Rack, or talk to our team about what a one-quarter rollout looks like for your stack.