Part 34 of 40 · 5 min read
A small deployment that can grow into a dependable platform
Experimental · Work in progress · Internal R&D
A proposed AWS and GCP architecture with durable storage, scoped identities, background work and recovery drills.
Arunank Sharan · Kuzushi Labs ·
In this article
The internal prototype runs locally and proves useful domain contracts. Moving it to a cloud account requires more than putting the API in a container. The production boundary needs authenticated identity, durable state, recoverable jobs, secrets, observability and a tested way to restore the company records.
For a solo founder, I would start with a small number of independently understandable services. A large Kubernetes estate is not a prerequisite for the first controlled business loop. The architecture below is a deployment design for the next stage, not a claim that this R&D platform already operates on both clouds.
Keep the web request short
The API authenticates the operator, validates the request and writes the business intent plus outbox event transactionally. It returns a durable task identity. Workers perform model calls and connector operations outside the request transaction. The cockpit reads current state and receives updates through polling or a separately controlled event channel.
Store documents in object storage and references in the database. Keep source revisions and digests. The queue carries identifiers and minimal routing data, not complete customer documents or credentials.
| Responsibility | AWS option | GCP option |
|---|---|---|
| API and cockpit backend | ECS service behind an application load balancer | Cloud Run service |
| Short asynchronous work | ECS workers consuming SQS | Cloud Tasks invoking a private Cloud Run worker |
| Operational database | RDS for PostgreSQL | Cloud SQL for PostgreSQL |
| Evidence objects | S3 | Cloud Storage |
| Secrets | Secrets Manager | Secret Manager |
| Scheduled wakeups | EventBridge Scheduler | Cloud Scheduler |
| Logs and metrics | CloudWatch plus chosen trace backend | Cloud Logging/Monitoring plus chosen trace backend |
These are alternative compositions, not instructions to run duplicate cloud stacks. Choose the provider that fits the existing operating environment and keep the domain contracts portable.
Separate service identities by responsibility
The public API should not inherit payment-provider credentials simply because another worker uses them. A read-only research worker needs different access from a dispatch worker. The outbox relay needs queue publication, while the task handler needs only the resources required by that task class.
ECS distinguishes the task role used by application code from the task execution role used for container startup responsibilities. Keep those permissions separate and narrowly scoped. ECS IAM roles.
On GCP, Cloud Tasks can invoke a private Cloud Run service using a service account and an authentication token. The enqueuer, invoking identity and runtime service account have different responsibilities. Restrict invocation to the intended worker rather than exposing an unauthenticated task endpoint. Cloud Tasks with Cloud Run.
Assume a task can arrive again
A queue acknowledgement should follow durable completion of the step. If the worker times out after creating an effect, a redelivery must consult the operation record. Queue delivery semantics do not replace business idempotency.
Cloud Tasks documents circumstances involving duplicate execution and does not guarantee execution order. Build the same deduplication and state checks that the local lab exercises. Cloud Tasks pitfalls.
For work longer than the request/task envelope, split it into resumable steps or use a job/worker execution model. Do not start a background coroutine in a request handler, return success and assume it will continue indefinitely. Persist the next step before yielding responsibility.
Put tenant scope into the data boundary
Every business record, receipt and query needs an authenticated tenant scope. PostgreSQL row-level security can add defence in depth, but application identity must set the scope through a trusted path. Table ownership and privileged roles can bypass ordinary policies; use appropriately restricted runtime roles. PostgreSQL row security.
A schema sketch for the operation ledger is deliberately small:
CREATE TABLE operations (
tenant_id text NOT NULL,
operation_id text NOT NULL,
request_digest text NOT NULL,
status text NOT NULL CHECK (status IN ('UNKNOWN', 'CONFIRMED', 'REJECTED')),
provider_receipt text,
updated_at timestamptz NOT NULL DEFAULT now(),
PRIMARY KEY (tenant_id, operation_id)
);
Add the appropriate access policy, indexes, transition checks and audit history in the deployed migration. The primary key makes identity explicit; it does not by itself prevent a tenant from reading another tenant's row.
Bound database and provider concurrency
A sudden increase in worker instances can overwhelm database connections or a provider quota. Limit instances, connection-pool size, task dispatch rate and per-provider concurrency together. Scale from queue age and observed service time, not merely CPU usage during network-bound model calls.
For an illustrative planning exercise, ten workers each holding four database connections imply up to forty worker connections before API and maintenance traffic. That arithmetic informs a connection budget; it is not a recommended instance count or measured platform capacity.
pilot_limits:
concurrent_tasks_per_tenant: 2
outbound_actions_require_review: true
maximum_uncertain_operations: 3
pause_on_critical_failure: true
provider_rate_policy: configured_per_connection
These are example pilot controls. Tune them from observed task duration, provider quotas, founder review capacity and recovery behaviour.
Backups matter only if restoration works
Back up the operational database and evidence objects with a stated recovery objective. Restore into an isolated environment, verify linked revisions and receipts, then replay only the work that is demonstrably incomplete. A restored queue may contain tasks whose external effects already happened before the backup boundary.
Keep secrets and live connector dispatch disabled during restoration drills. Validate that the restored system can explain the status of a known quote, invoice and uncertain send without contacting customers.
Deployment acceptance should include a worker kill, duplicate delivery, revoked credential, database connection exhaustion and backup restore. Record measured recovery times when those tests run. The platform becomes ready for a controlled pilot when those behaviours are understood, not when the cloud dashboard shows green containers.