Resolve Solutions Logo Resolve Solutions
← All posts
18 min read

How I Architected the ResolveAI Backend: FastAPI, AWS Lambda, DynamoDB, and Event-Driven AI Workloads

A practical look at the serverless backend behind ResolveAI: why I chose FastAPI on Lambda, DynamoDB access patterns, Firebase auth, SQS workers, and EventBridge scheduling.

ResolveAIResolveSolutionsBackendArchitectureFastAPIPython312AWSLambdaAPIGatewayDynamoDB
ResolveAI needed a backend that could move fast like a startup, but stay stable enough to support real users, sensitive data, AI features, subscriptions, and caregiver workflows.

ResolveAI is built around a practical idea: move fast like a startup, but make the backend stable enough to support a real consumer SaaS product with real users, sensitive data, AI features, subscriptions, health context, community workflows, and caregiver experiences.

The backend is not a traditional always-on server. It is a serverless API platform built with Python 3.12, FastAPI, AWS Lambda, API Gateway, DynamoDB, SQS, EventBridge, and external services including Firebase, OpenAI, RevenueCat, and Google APIs.

The goal was to create an architecture that could support multiple product domains without turning into a fragile monolith too early. ResolveAI includes journals, moods, AI chat, insights, caregiver features, health metrics, addictions and recovery workflows, subscriptions, onboarding, spaces and community, admin tooling, and background processing.

See the cross-platform mobile architecture companion: How I Designed Resolve Reinvent Flutter Architecture

So the architecture had to balance three things:

  • Speed of development
  • Low operational overhead
  • A clean path to production reliability

Why This Architecture Was Chosen

I did not want Kubernetes, a fleet of microservices, or a large DevOps footprint. A serverless architecture made sense because API traffic can scale without managing servers, Lambda keeps baseline cost low, FastAPI gives a clean Python developer experience, DynamoDB supports high-scale low-latency access patterns, SQS separates real-time requests from slower background processing, EventBridge handles schedules, and AWS SAM plus CloudFormation keep infrastructure versioned and repeatable.

The tradeoff is discipline. API Gateway routes, Lambda timeouts, authorizer behavior, IAM policies, DynamoDB indexes, and cold starts all need to be understood. You avoid servers, but you still have to design the system carefully.

API Layer: FastAPI on Lambda

The main API runtime is FastAPI running on AWS Lambda through Mangum. FastAPI gives ResolveAI domain routers, dependency injection, Pydantic request and response models, clear route/model/service separation, centralized exception handling, and strong local development ergonomics.

The important design decision was to use one API Lambda for the main synchronous surface instead of splitting every route into its own function. That keeps deployment and routing simpler while the product is still evolving quickly.

The current route groups include journals, AI and conversations, moods, spaces and community, auth, users, admin, badges, breathing, insights, settings, disclaimers, sleep sounds, health metrics, addictions and recovery, subscriptions and paywall, onboarding, reinvention, and caregiver features.

Four Custom Domain Workflows That Shaped ResolveAI

These are four domain capabilities that show both product depth and backend architecture decisions in production.

  1. AI-assisted journals (SQS + Lambda)

    Journal writes stay fast on the synchronous path, while AI assist runs asynchronously. Journal events can be queued to SQS and processed by Lambda workers for tasks like spell correction and automatic title generation. That keeps user latency low while still delivering richer journal output.

  2. Insights with admin-controlled prompt orchestration

    Insights are driven by specialized prompts that are configurable through the admin interface. Admin controls include prompt tuning, drill-down behavior, and conversation startup policy, such as auto-starting a chat immediately or deferring it until the user answers an initial question.

  3. Injected account context for better AI relevance

    We introduced a context-injection model that assembles recent user signals into AI requests, including journal entries, mood data, and location context. More recently, health and fitness signals were added as part of the same context envelope so insights and conversations can be grounded in current user state.

  4. Resolve Spaces at scale: paging + deferred AI moderation

    Spaces combines cursor-based infinite scrolling for high-volume message history with deferred moderation workflows. Messages can be reviewed by AI moderation queues before full visibility, while admin tools retain override control for governance.

API Gateway Routing: One Small Detail That Matters

FastAPI routing and API Gateway routing are not the same thing. When a new route family is added in FastAPI, the corresponding API Gateway path also needs to be registered in the SAM or CloudFormation template.

/v1/
/v1/{proxy+}

Both the base path and proxy path matter. If this is missed, a route can work locally but fail in the deployed environment with confusing CORS or 403 behavior.

The rule is simple: when adding a new route family, update both the FastAPI app and the infrastructure template so they stay aligned.

Authentication vs Authorization

ResolveAI uses Firebase as the identity provider. The client signs in with Firebase, sends a Firebase ID token as a bearer token, API Gateway invokes a custom Firebase Lambda authorizer, the authorizer validates the token with the Firebase Admin SDK, and FastAPI dependencies extract the user context inside the app.

Authorization: Bearer ...

Authentication answers who the user is. Authorization answers what the user is allowed to do. ResolveAI uses API Gateway JWT validation, FastAPI account-status dependencies, admin route checks, and separate webhook authentication patterns so privileged access stays out of normal route logic.

DynamoDB Data Architecture

ResolveAI uses DynamoDB with single-table-style patterns. The primary tables are resolveddb-, spacesddb-, and addictionsddb-. The main table holds core entities across multiple domains, while spaces and addiction/recovery each have their own tables.

The key strategy uses namespaced partition and sort keys, such as:

pk = USER#
sk = PROFILE

Other key namespaces include USER#, INSIGHT#, HEALTHMETRIC#, and FAMILY_MEMBER#.

The point is to model data around access patterns, not around relational tables. Representative examples include a user journal timeline, admin user profile listing, health metric lookup, insight usage and voting, and family plan lookup.

The main table includes the gsi1-journal-date-desc-idx and gsi2-idx indexes. The spaces table uses gsi1 and gsi2.

DynamoDB Guardrails

The main production rule is query first. Avoid broad table scans in production paths. That means new features need to define access patterns early, then use explicit key conditions, GSI-driven reads, projection expressions, cursor-based pagination, conditional writes, and soft-delete or status flags where appropriate.

Engagement Dashboard: Counters, Summaries, and DynamoDB Tradeoffs

Another custom area is the admin engagement dashboard. We needed reliable summaries for activity and adoption without turning every dashboard load into expensive table scans.

DynamoDB makes this a design problem: precise global counts from ad-hoc scans are expensive at scale, while pure real-time counters can become noisy across many write paths. We chose a middle-ground architecture that mixes lightweight counters with periodic summary jobs.

The pattern is:

  • Track domain-level counters during writes where the signal is clear.
  • Use scheduled or queue-driven aggregation to build dashboard summary records.
  • Avoid broad scans on the hot path for admin dashboard reads.
  • Accept eventual consistency for some rollups, while keeping critical metrics tight.

In practice, that gave us stable engagement metrics, faster dashboard responses, and lower read-cost volatility compared with scan-heavy counting.

The key architectural decision was to treat engagement summaries as their own read model, not as a direct reflection of raw event tables on every request.

Resolve Spaces: Unlimited Scrolling, Paging, and Replies

One concrete example of query-first design is Resolve Spaces chat. The goal was to support effectively unlimited message history without loading entire rooms into memory.

The client requests messages in pages using a cursor token. Each response returns the next cursor when more data exists. The app can keep asking for the next page as the user scrolls, which gives an infinite-scroll experience while keeping payloads small and latency predictable.

Replies are stored as first-class messages with reply metadata, not as a separate data model. That keeps write paths simple and makes reply threads queryable without changing the core message pipeline.

At the API layer, the pattern is straightforward: the first page reads newest messages, older pages use the cursor, and reply context is included in each message payload so the UI can render reply targets immediately.

GET /v1/spaces/{spaceId}/messages?limit=50
GET /v1/spaces/{spaceId}/messages?limit=50&cursor=eyJwayI6Ii4uLiJ9

A simplified message shape looks like this:

{
  "pk": "SPACE#abc123",
  "sk": "MESSAGE#2026-06-29T15:20:11.045Z#msg_01J...",
  "messageId": "msg_01J...",
  "spaceId": "abc123",
  "authorUserId": "uid_456",
  "body": "This is the message body",
  "createdAt": "2026-06-29T15:20:11.045Z",
  "replyToMessageId": "msg_01H...",
  "replyToUserId": "uid_123",
  "status": "active"
}

The key detail is that paging, ordering, and reply linkage are all represented in the same message item model. That is what makes the experience feel unlimited to users while still behaving like a bounded, efficient backend system.

Request Lifecycle Walkthrough

A typical authenticated request starts when the app sends a request to API Gateway, such as POST /v1/journals with a bearer token. The Firebase authorizer validates the token, checks revocation, and returns a policy with user context. API Gateway forwards the request to the main Lambda, Mangum converts it into an ASGI request, and FastAPI routes it to the journals service.

The service layer validates the body, normalizes DynamoDB-compatible values, builds the keys, and writes the journal entry. If the request triggers a non-critical side effect, that work can be pushed to SQS instead of blocking the user.

The response returns quickly to the client, while longer-running work is handled asynchronously. That split is important: the user path stays fast, and the background path can be slower, retried, monitored, and sent to a DLQ if needed.

Sync vs Async Workloads

Synchronous work includes validating the user, reading or writing primary data, returning app state, enforcing account status, checking authorization, and handling user-facing API responses. Asynchronous work includes community moderation, mention processing, longer AI tasks, insight generation, notification fanout, cleanup jobs, and metrics aggregation.

ResolveAI uses SQS queues for moderation, mentions, and generic async tasks, each with its own DLQ. Dedicated Lambda workers process those queues so a failure in one workload does not break the core API.

AI Moderation Queue and Admin Controls

Resolve Spaces moderation is intentionally queue-driven. New messages can be written in a pending moderation state, then sent to a dedicated moderation queue for AI review before they are fully visible.

The moderation worker applies custom prompts and policy instructions tuned for community safety. The result is a structured decision payload, typically allow, deny, or escalate. Approved messages are promoted to active status, denied messages are blocked, and uncertain cases can remain queued for follow-up.

This design keeps moderation off the critical request path while still enforcing policy quickly. It also gives each decision an audit trail that can be inspected when needed.

Admin tooling adds a second control layer. Admins can clear queued items, deny or allow users, and remove posts when policy or context requires a human override. In practice, AI does the bulk moderation with specialized prompts, and admins retain final governance.

Scheduled Workloads with EventBridge

Some work is not triggered by a user request. EventBridge handles daily reminders, metrics aggregation, conversation cleanup, stale soft-delete cleanup, addiction check-in reminders, and pending-deletion account purges without needing a cron server.

Third-Party Integrations

Firebase handles authentication, token verification, Firebase Admin SDK behavior, and push notifications. OpenAI powers conversational responses, assistant-style interactions, moderation, mention workflows, @lotus interactions, caregiver note autocorrect, and longer async AI processing. RevenueCat handles subscription state and entitlement workflows. Google APIs support location-aware features. Apple Health data is client-originated and ingested by the backend for health-aware insight flows.

Firebase Cloud Messaging for Routine Check-Ins

FCM is also part of the engagement system. We use it for routine reminders such as daily tasks, scheduled check-ins, and weekly wellness nudges so users get timely prompts without reopening the app manually.

The backend controls when these notifications are sent through scheduled workflows and account-aware logic. That keeps reminders consistent with user state and allows admin visibility into notification behavior when troubleshooting engagement drops.

AI calls are isolated, logged where appropriate, retried safely, and moved off the user path when they are too slow or failure-prone. Subscription state is tracked server-side because that truth should not live only on the client.

Observability and Reliability

ResolveAI uses API Gateway access logs, Lambda logs in CloudWatch, CloudWatch alarms, SNS alarm notifications, SQS queue depth monitoring, Lambda error and throttle monitoring, API 4xx and 5xx monitoring, and DynamoDB operational indicators. There is also an optional AI audit logging path to S3 for controlled diagnostic data.

Reliability patterns include SQS dead-letter queues, workload-specific Lambda timeouts, explicit EventBridge permissions, DynamoDB backups, S3 lifecycle rules, and environment-aware infrastructure behavior. Production DynamoDB tables are treated more carefully than non-production tables to reduce destructive risk during stack operations.

Security and Privacy Practices

ResolveAI handles sensitive personal data, so the backend has to be designed with security and privacy in mind. The core practices are JWT authentication at the edge, Firebase token verification with revoked-token checks, app-layer account status enforcement, admin-only route dependencies, secrets in AWS Secrets Manager, private S3 buckets, webhook authentication, IAM roles scoped by function responsibility, and soft-delete plus legal-hold account states.

Because this platform stores journals, wellness, and fitness context, the baseline security posture is strict: TLS in transit across client and API calls, encryption at rest in DynamoDB and S3, and AWS KMS-managed keys with rotation controls for sensitive workloads.

Authentication and authorization are enforced through JWT-based identity flows plus layered backend checks. Admin capabilities are intentionally built into the platform so the team can monitor users, investigate incidents, apply policy decisions, and respond quickly when risk patterns appear.

A valid token is not enough if the account is suspended, disabled, under legal hold, or pending deletion. That type of account-state enforcement belongs in the backend request path, not only in the client.

Python Service-Layer Patterns

The backend code is organized around domain modules with routes, models, CRUD functions, service logic, validation, and dependencies. FastAPI dependencies handle current-user extraction, optional auth, required auth, admin checks, account-state checks, and request controls. Pydantic models keep request and response shapes explicit, and DynamoDB numeric types are normalized for JSON serialization.

Lessons Learned

Serverless does not remove architecture work. It changes where the work happens. The important decisions are route definitions, Lambda boundaries, DynamoDB access patterns, SQS retry behavior, IAM scope, secrets management, observability, async workload design, and production data safety.

A single FastAPI Lambda can be an effective middle ground. It gives the developer experience of a modern Python API with the operational profile of Lambda, without forcing a tiny function-per-endpoint model or a large containerized service.

DynamoDB also works best when you are honest about access patterns. If you treat it like a relational database, you will fight it. If you design around queries, GSIs, and item collections, it can be extremely effective.

Tradeoffs

The main tradeoffs are API Gateway plus FastAPI route duplication, a single API Lambda that can grow over time, DynamoDB modeling complexity, async debugging, and serverless limits like timeouts, payload sizes, and cold starts.

Final Thoughts

ResolveAI’s backend is designed to support a real consumer SaaS product without overbuilding too early. FastAPI gives the API layer structure. Lambda keeps operations lean. API Gateway and Firebase handle the authenticated edge. DynamoDB provides scalable persistence when modeled around access patterns. SQS and EventBridge separate immediate user actions from background processing. Secrets Manager, IAM, CloudWatch, SNS, S3, and AWS Backup provide the operational foundation.

The architecture is practical, not perfect. It gives ResolveAI room to grow across journals, moods, AI insights, caregiver support, health context, subscriptions, community spaces, and recovery workflows without forcing a large-platform design too soon.

That is the balance I wanted: startup speed, production discipline, and enough architectural clarity to keep evolving.

If you need help with AWS, hybrid cloud, cloud integration, or modernization work, please reach out through the contact page.