Make informed build-versus-buy decisions for platform components. Covers total cost of ownership analysis, evaluation criteria, vendor lock-in assessment, hybrid approaches, and the decision framework that prevents both NIH syndrome and vendor dependency.
When building or evolving a platform, teams face a fundamental decision: build the platform in-house or buy an off-the-shelf solution. The Platform Build vs. Buy Framework provides a structured way to evaluate this choice across technical, operational, and organisational dimensions. It matters when a team has a clear understanding of their developer needs but must decide whether to invest in a custom platform or adopt a pre-built one, especially at scale.
The framework evaluates options along five core dimensions: capability fit, integration complexity, operational burden, evolution path, and ownership model. Each dimension guides a specific decision-making activity.
Assess how well a candidate platform satisfies current and near-term developer needs. Start by listing core platform capabilities as a set of requirements.
- Provision environments (dev, staging, prod)
- Deploy applications via Git push
- Centralized logging and monitoring
- Secrets management with versioning
- Automated testing on PRs
- Feature flag management
- Infrastructure as code (IaC) templates
- Developer self-service dashboard
For each requirement, evaluate how well the platform meets it. A buy option is compelling if it satisfies 80% or more of these requirements with minimal configuration. A build option is justified when the platform must handle unique workflows or non-standard integrations.
The key signal of poor fit is missing or inadequate configuration. When a buy platform lacks a field for environment-specific secrets, developers must fall back to manual processes or ad hoc scripts. A common failure mode is the platform.yaml file that is not applied during deployment:
environments:
dev:
region: us-east-1
instance_type: t3.small
secrets:
DATABASE_URL: "dev-db.example.com"
API_KEY: "dev-key-123"
If the platform ignores platform.yaml and instead expects platform-config.json, the mismatch becomes evident during CI runs:
$ kubectl logs deploy/platform-controller -c deployer
Error: failed to parse platform configuration: missing field 'environments' in struct PlatformConfig
This error indicates a gap in capability fit and forces teams to either adapt their workflow or build a bridge layer.
Evaluate how easily the platform integrates with existing tools. Use the curl command to simulate real integration scenarios.
curl -X POST https://api.platform.example.com/integrations \
-H "Authorization: Bearer $PLATFORM_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"source": "gitlab",
"project_id": "12345",
"webhook_url": "https://ci.example.com/webhook/platform",
"events": ["push", "merge_request"]
}'
A platform is well-integrated if all required fields in the API response are present and correctly mapped. When a platform returns {"error": "unknown event type"} for merge_request, the integration fails silently.
The most common silent failure is event delivery without acknowledgment. A platform sends a deployment-completed event to a message queue, but the consumer does not process the message. After 3 days, the team discovers that the deployment dashboard is missing 47% of deployments.
To catch this, use kafka-topics.sh --describe --topic platform.events and check consumer lag:
$ kafka-topics.sh --describe --topic platform.events
Topic: platform.events PartitionCount: 4 ReplicationFactor: 3
...
Partition: 0 Leader: 1 Replicas: 1,2,3 Isr: 1,2,3
Current offset: 12345
Log end offset: 12345
Lag: 0
If lag is increasing, the integration is under stress. A missing or misnamed event_id field in the message payload is a frequent culprit.
Determine how much effort is required to keep the platform running and up to date.
For a buy platform, the burden is measured by the number of platform-specific configuration files and scheduled maintenance tasks.
$ ls -la /etc/platform/
total 12
drwxr-xr-x 4 root root 4096 Apr 5 10:00 .
drwxr-xr-x 10 root root 4096 Apr 5 10:00 ..
-rw-r--r-- 1 root root 2341 Apr 5 10:00 config.yaml
-rw-r--r-- 1 root root 821 Apr 5 10:00 secrets.json
-rw-r--r-- 1 root root 1034 Apr 5 10:00 crontab
The crontab file defines daily tasks:
# Daily platform maintenance
0 2 * * * /usr/bin/platform-backup --all
0 3 * * * /usr/bin/platform-upgrade --stable
0 4 * * * /usr/bin/platform-analyze --metrics
If the platform-backup script fails silently—returning exit code 0 but not creating a backup file—the platform starts to degrade without alerting anyone.
A common failure occurs when a platform expects a platform-cert.pem file in /etc/platform/certs, but the team configures a platform.crt file instead. The platform logs:
ERROR: unable to load certificate: failed to open /etc/platform/certs/platform-cert.pem: no such file or directory
This error appears only under high load and is hard to detect without structured logging.
Evaluate how easily the platform can adapt to future needs.
A buy platform is attractive if it supports plugin architecture via plugins/ directories with plugin.yaml manifests:
# plugins/feature-flags/plugin.yaml
name: "Feature Flags"
version: "1.2.0"
author: "Platform Team"
dependencies:
- "platform-core >= 0.9.0"
- "auth-service"
hooks:
- on-deploy: "feature-flags.onDeploy"
- on-pr: "feature-flags.onPR"
But the framework identifies a common pitfall: plugin lifecycle mismatch. A plugin is deployed, but its onDeploy hook is not registered in the platform’s event registry. After 3 weeks, platform.log shows:
WARN: Plugin 'feature-flags' not found in event registry; function 'onDeploy' not available
This indicates that the evolution path is not well-defined. The platform assumes plugins are registered, but no mechanism exists to discover or register them.
A build platform excels here: it allows custom code to be shipped with the platform. Use git to version and deploy platform changes:
$ git checkout -b feature/upgrade-logging
$ git add .
$ git commit -m "Add structured logging to deployment pipeline"
$ git push origin feature/upgrade-logging
$ git merge feature/upgrade-logging
$ git push origin main
The main branch is automatically deployed via CI. The platform’s docker-compose.yml defines the deployment:
version: '3.8'
services:
platform-api:
build: .
ports:
- "8080:8080"
depends_on:
- postgres
volumes:
- ./config:/app/config
environment:
- DATABASE_URL=postgres://db:5432/platform
- LOG_LEVEL=info
A common failure is missing environment variables in the docker-compose.yml. The platform starts but logs Error: DATABASE_URL not set, even though the variable is defined in the docker-compose.yml.
Determine who is responsible for the platform and how they interact with it.
A buy platform assumes a shared ownership model: developers use the platform, but platform engineers maintain it. This model fails when developers expect to customize the platform but lack access.
The framework identifies two critical ownership signals:
platform init and receive a platform-config.json file:$ platform init
Creating project: myapp
Initializing platform configuration...
Writing to platform-config.json
Initializing git repository...
Initialized empty Git repository in /home/user/myapp/.git/
$ cat platform-config.json
{
"project": "myapp",
"team": "frontend",
"environments": ["dev", "staging", "prod"]
}
The platform init command fails silently if platform-config.json is not present in the project root. The error message is:
Error: failed to initialize platform: config file not found at ./platform-config.json
This failure is common when developers clone a repository but forget to run platform init.
A buy platform uses a versioned update mechanism:
$ platform version
Current version: 2.1.3
Latest version: 2.3.0
$ platform update
Downloading platform version 2.3.0...
Applying migrations...
Updating plugins...
Restarting services...
$ platform status
Platform: 2.3.0 (updated)
Plugins: 4/4 up to date
Services: 5/5 running
But the platform update command fails if the migrations/ directory is missing:
Error: no migration files found in migrations/
A silent failure occurs when platform update runs, but the new version is not activated. The platform status shows the old version, but platform version returns the new one. This mismatch signals a misaligned ownership model.
Apply the framework using this workflow:
The framework is complete when a team can answer: “If we build this platform, what will change?” and “If we buy it, what will stay the same?”
The framework surfaces several sharp edges:
config.yaml is updated in production, but the platform.yaml file is not deployed. The platform runs on old settings for weeks.deployment-completed event is sent multiple times, but the system processes it twice, creating duplicate records.v1.0.0 but does not track version history in platform.log.platform update, a service fails to restart due to missing restart.sh script.These failures are not captured in documentation but emerge only through real use.
The Platform Build vs. Buy Framework is a practical, concrete guide for engineering teams making strategic decisions about their platform. It avoids abstraction by grounding every decision in real commands, configuration, logs, and failure modes. It does not assume a specific product but describes patterns that work across any platform environment. The framework makes the invisible visible: what is expected, what is assumed, and what silently breaks.
This page was rewritten on 18 October 2026. It replaced a templated version that was not specific to its own title. How these pages are written and checked. If anything here is wrong, tell us at [email protected] and we will correct it.
We use cookies for analytics (Google Analytics) and advertising (Google AdSense) to improve your experience and support free content. Privacy Policy