HomeCareerProjectsServicesStackBlogContact
Sign in
HomeCareerProjectsServicesStackBlogContact

Made with coffee, code and curiosity, from Colombia ☕

japalacio-08jeyson-anibal-palacio-palma

Resume

Download CV
Should I deploy today?ThursdayNoNot today

© 2026 Jeyson Palacio. All rights reserved.

Privacy PolicyTerms of ServiceCredits
All services

Backend Architecture & APIs

Your product ends up with a backend that survives growth: services with clear boundaries, documented APIs and a data model built for the queries that actually run.

This usually starts in one of two ways. Either a new product needs its backend built and the data model and the contracts had better be right, or there is a backend that works but every change costs more than the last one.

The two cases get different treatment. On a new product the focus is laying foundations that survive growth; on one already running, removing what slows the team down without stopping delivery.

Where the work goes

API design

Contracts are agreed with you before implementation. Every endpoint has its schema, its error codes and its version, so your client team can move in parallel against that contract. When several teams consume the API, contract tests go in, so a change does not silently break anyone.

Data model

The schema is the most expensive thing to change later, so it gets time up front: keys, relations, what gets normalised and what does not, and which indexes the queries that will actually run need. Migrations are written so they can ship without stopping the service.

Background work

Anything that does not have to answer within the request goes to a queue: emails, webhooks, reports, syncs. With retries, idempotency and a dead letter queue somebody actually looks at, because a queue without observability just hides errors.

Frontend when needed

Many backends need an internal console or an admin panel to operate them. Those get built with React, Next.js or Angular, to the same standard: real loading and error states, and no screens that only work with perfect data.

How it fits together

The path of a request

What has to answer fast, and what gets done afterwards, outside the request.

  1. Client

    Web, mobile or a third-party integration. They all come in through the same door.

  2. Edge

    Authentication, tenant permissions and rate limiting before anything is touched.

  3. Service

    Business rules, kept apart from the framework and with their own tests.

  4. PostgreSQL

    One transaction per operation, so no write is left half done.

What is not resolved inside the request

Queue (Celery / Sidekiq)Retries with backoffWebhook or notification

Where to draw the line between tenants

This is the decision that costs the most to change later. It depends on how many customers there are and how much isolation the contract asks for.

tenant_id column

  • A single database and a single set of migrations
  • Isolation depends on the code, so it gets tested on every query
  • Row level security when the data is sensitive

Works with many small customers and a team that can keep the discipline.

Schema per tenant

  • Tables are repeated, the connection picks the schema
  • Migrating means walking every schema, one by one
  • Restoring a single customer stops being a problem

A good middle ground when there are dozens of customers and one of them asks for separate data.

Database per tenant

  • Real isolation, including performance
  • More moving parts to operate: connections, backups, deploys
  • Each customer can move at its own version pace

Justified with a few large customers or with compliance requirements.

What it includes

  • REST and GraphQL APIs with versioned, documented contracts and contract tests.
  • Services in Python (Django, FastAPI), Node (NestJS, Express), Deno or Ruby on Rails, depending on what your team already runs.
  • PostgreSQL data model: schema, indexes, migrations and queries that do not degrade as the table grows.
  • Async work on queues (Celery, Sidekiq, BullMQ) for anything that should not block a request.
  • Authentication and authorization: sessions, JWT, OAuth, roles and permissions, plus tenant separation when there are several clients.
  • Redis caching where it is actually needed, with invalidation thought through before it is written.
  • Tests for the critical paths with pytest, RSpec or Jest, and fixtures that do not depend on production.
  • Observability from day one: logs with context, metrics and distributed traces.

How the project runs

  1. 01Before anything is proposed, what already exists gets reviewed and whoever maintains it gets heard.
  2. 02API contracts and the data model are agreed with you before any implementation is written.
  3. 03Delivery comes in increments that can be deployed, so something is running from the first week.
  4. 04What stays behind: tests for the critical paths and docs on how it is operated.

What you get

  • Services in production, with their deployment pipeline.
  • API and data model documentation.
  • A test suite covering the critical paths.
  • An operations guide: what to look at when something breaks.

Usual stack

Python
DjangoDjango REST FrameworkFastAPICelerySQLAlchemypytest
Ruby on Rails
ActiveRecordActiveJobSidekiqDeviseCanCanCanRSpecSorbet
JavaScript / TypeScript
NestJSExpressDenoNode.jsPrismaJest
APIs
RESTGraphQLOpenAPIJSON SchemaWebhooks
Data
PostgreSQLRedisMongoDBS3
Frontend
ReactNext.jsAngularTypeScript

Where this has been done

  • StyleSeatStyleSeatBeauty & wellness marketplace · via Revelo
  • CoderPadCoderPadTechnical interview platform
  • CinemarkCinemarkCinema digital platform

Frequently asked questions

Can the work happen on a backend that is already in production?

Yes, and that is the usual case. The work goes in as increments that ship on their own: one part of the system gets scoped, covered with tests and then changed while delivery keeps running. Nobody has to freeze the product for weeks for this to move.

What happens to the team already maintaining the code?

They keep owning the code. Contract and data model decisions are agreed with them, and what stays behind is the test suite and the operations docs, so they can keep going without depending on anyone external.

Which language should it be built in?

The one your team can maintain. Python with Django or FastAPI, Ruby on Rails and Node with NestJS or Express cover much the same ground; the choice comes from what the team can operate and what is already running, not from this year fashion.

How do you know the backend will survive growth?

From the data model and the boundaries between services, which are the expensive things to change later. Queries get reviewed against the expected volume, not against the development database, and anything that does not have to answer inside the request goes to a queue from the start.

Another question?Send it over and you get an answer, no meeting required.
Talk about your project