Series · 7 parts Published May 15, 2026

Social scheduler

A serverless scheduler that lets a small business draft every social post in one place, holds a calendar of when each one should go out, checks each post against the rules for the platform it’s headed to, posts it at the scheduled time to the chosen channels, and reports what went out and what failed. Nothing leaves until a human approves it. Seven posts on the same system — one diagram at a time — with an engineering reference at the end.

  1. 01

    A social scheduler on AWS for a few dollars a month

    The whole system on one page — a post intake, a scheduler, and a sender, plus the four moves they share for every post.

  2. 02

    How a post gets drafted

    Three lanes feed the queue — the Drive sheet itself, an optional draft-helper that roughs out text from a short note for one-tap approval, and a recurring-template lane that drops standing posts onto the calendar.

  3. 03

    How the schedule fires on time

    A daily tick reads the calendar, computes when each approved post is due, books a one-off send for the exact minute, and picks one of four moves: resting, queue, send, retry. No model on the tick.

  4. 04

    How a post gets formatted per channel

    Format checks per channel, image rules, link limits, token freshness, the per-channel send, and the four guardrails between a due post and the post actually landing.

  5. 05

    How a post gets approved or held

    Three actions on the Review button: approve (lock it in for its time), hold (pull it back to draft without losing it), and send now (push it out immediately). Every action is logged.

  6. 06

    What the social scheduler costs

    A couple of dollars a month at SMB volume. The scheduler runs once a day, calls no models on the tick, and only fires Bedrock on the optional draft-helper and the monthly recap.

  7. 07

    Engineering reference: the social scheduler architecture

    Same system, drawn purely for engineers. Service names, resource identifiers, region, Bedrock model IDs, Lambda inventory, IAM scopes, the channel-token setup, EventBridge Scheduler config, and the DynamoDB schemas.

What is a social scheduler?
A small serverless system that lets a small business draft social posts in one place, holds a calendar of when each post should go out, checks each post against the rules for the platform it’s headed to, posts it at the scheduled time to the chosen channels, and reports what went out and what failed. Nothing posts until a human has approved it.
How much does it cost to run?
About $2/month at typical small-business volume (around 60 posts a month across a few channels). The fixed cost is essentially zero. The variable cost is dominated by the daily tick and the send Lambdas; Bedrock fires only on the optional draft-helper and the monthly recap, so they’re small slivers. At 600 posts a month the bill lands around $9.
Which AWS services does it use?
Lambda (Python 3.14, arm64) with Function URLs for the approval buttons, EventBridge Scheduler for the daily tick and the per-post one-off send times, DynamoDB on-demand, S3 (with versioning), SES outbound, Secrets Manager, CloudWatch Logs (7-day retention), AWS Budgets, and Bedrock (Claude Haiku 4.5 via Global cross-Region inference) for the optional draft-helper and monthly recap. No API Gateway, no NAT Gateway, no always-on compute.
Where do the posts live?
In a Google Sheet in a Drive folder. One row per post with the text, the channels, the scheduled date and time, a link to the image in the same folder, and an approval flag. A small drive-sync Lambda mirrors the sheet and images to S3 every five minutes; the scheduler reads from S3 to keep Drive API calls predictable and to get S3 versioning for free.
Does the scheduler use AI?
Sparingly. The daily tick and the send path use no AI — they’re plain Python that reads times, checks formats, and posts. Bedrock Haiku 4.5 fires only when the owner asks the optional draft-helper to rough out post text from a short note, and once a month for the recap. Most of the system is deterministic by design.
How does it avoid posting something broken?
Every post passes a format check before it can be queued — the right character limit per platform, image size and type the platform accepts, link count, and whether the channel token is still valid. A post that fails any check is flagged back to the owner with the exact reason instead of being sent. And no post leaves at all unless its approval flag is set, so a half-finished draft never goes out by accident.
What happens after a post is approved?
Three buttons on every queued post: Approve locks it in for its scheduled time. Hold pulls it back to draft without losing it. Send now pushes it out immediately. On approve, the scheduler books a one-off EventBridge Scheduler rule for the exact minute the post is due. Every action is recorded in the ss-audit DynamoDB table with timestamp, post, action, by-user, and a before-and-after snapshot, so the trail is auditable.
All posts