← Back
Home › Systems › Sales, marketing and customer service

social-media-management

Lets a team plan, publish, monitor and report on many social media accounts from one place, connecting each account through that network's own API.

Hootsuite, Buffer

Open the social-media-management pagesocial-media-managem… Hdr histogramdata-structures: Log-linear bucketed histograms with bounded relative error for latency percentilesDeterministic simulationtestingdistributed: Run the whole system in one thread under a seeded scheduler with simulated network, disk and clock, so every failure replays from its seed.›Durable job queuedistributed: Persisted tasks that workers lease for a visibility timeout, ack on success and retry with backoff; at-least-once execution that survives worker and queue crashes.›Primary-backup replicationdistributed: One node orders all writes and ships them to standbys; the acknowledgement rule (none, one, all) sets what a crash loses, and an external arbiter decides who takes over.›Image resampling filtersgraphics: Resize an image by convolving with a kernel (box, triangle, cubic, Lanczos) whose width scales with the shrink factor, done as two separable 1-D passes with precomputed weights.›Process supervisionhardware-os: A parent process starts services, reaps their exits and restarts them under a delay and burst-limit policy, then stops them with SIGTERM before SIGKILL.›Language identificationmachine-learning: Score a text's character n-grams against per-language statistics, after a cheap script check, and return an ISO 639 code with a confidence or "und".›Named entity recognitionmachine-learning: Find the character spans of entities in text and give each a type, by labelling every token and decoding a valid label sequence.›Near-duplicate detection withMinHash LSHmachine-learning: Estimate set Jaccard similarity from k min-hashes and find similar pairs with banded LSH buckets; the standard dedup for web crawls, training corpora and sequence collections.›Text classificationmachine-learning: Assign one or more labels to a text; climb a ladder from regexes to linear models on n-grams, embeddings, fine-tuned encoders and LLM prompts, only as far as the data and budget demand.›Video transcoding laddermedia: Turn one source into resolution x bitrate x codec renditions chosen from measured rate-quality points, cut on aligned keyframes so players can switch mid-stream.›Open and click trackingnetworking: Tracking pixels and signed redirect links for engagement eventsWebhook deliverynetworking: Reliable server-to-server HTTP callbacks: signed POSTs, 2xx-means-done, retries over days with jitter, endpoint disabling, SSRF guards and idempotent receivers.›Aho-Corasick multi-patternmatchingsearch-sort: Find all occurrences of many fixed patterns in one pass over the text, in time independent of the pattern count, using a trie with failure links.›Boolean expression indexingsearch-sort: Indexing conjunctive targeting expressions so one event finds all matching ads/subscriptions fastTime decay scoringsearch-sort: Scoring items by recency with exponential decay or half-life, combined with relevanceURL normalizationsearch-sort: Rewrite a URL to one canonical key, in safe RFC 3986 steps plus lossy, site-dependent ones (tracking parameters, query order, fragments), and keep the original beside the key.›Coverage-guided fuzzingsecurity: Mutate inputs, run an instrumented target, and keep any input that reaches a new code edge; feedback turns blind guessing into incremental search.›Dual control approvalsecurity: Four-eyes / maker-checker approval with quorum policies for sensitive operationsMutual TLSsecurity: TLS where the client also proves a certificate key, so every connection carries a verified, rotatable machine identity.›OAuth 2 and OpenID Connectsecurity: Delegated authorization (OAuth 2) and login on top of it (OIDC); use authorization code + PKCE for every user-facing client.›Time-series anomaly detectionstatistics: Predict the expected value from a seasonal baseline, scale the residual by a robust spread (MAD), threshold at a chosen false-alarm rate, then merge flags into incidents.›Inverted indexstorage: Map each term to a sorted, compressed list of the documents containing it; the core of full-text search and other fast set queries.›Point-in-time recoverystorage: Periodic base backups plus a continuously archived change log let you rebuild the state as of any instant, then branch from there.›Rollup aggregationstorage: Fold raw events into one mergeable partial aggregate per time bucket and dimension key, then merge fine buckets into coarser ones, so long ranges read few rows and stay exact.›Distributed rate limitingsystems: Enforce one rate limit across N servers: a central atomic counter, a limit split per node, or batched token leases, trading exactness against coordination cost.›Exponential backoff with jittersystems: Retry after delays that grow geometrically and are randomized, so failed clients spread out instead of hammering a recovering service in synchronized waves.›Graceful drainingsystems: On a termination signal, stop taking new work, finish in-flight work until a deadline, tell clients to reconnect elsewhere, then exit; clients resume from a token.›Hierarchical timing wheelsystems: Timers bucketed by expiry into wheels of slots, coarser wheels for far deadlines: O(1) insert and cancel for millions of timeouts.›Cooperative schedulingconcurrency: Green threads/coroutines yielding at await points on a user-space schedulerFault injectiondistributed: Inject latency, errors, kills and partitions via proxies, netem or hooksRecord replaydistributed: Record every nondeterministic input (time, randomness, I/O, model and tool outputs, per-tick player input) and re-execute deterministically for debugging, replays and state rebuildLeasesdistributed: A lock that expires on its own: bounded-time ownership that survives crashes and partitions, given bounded clock drift and fencing tokens on writes.›Health checkingsystems: Decide per backend whether to route to it using probes and real-traffic errors, with consecutive-count hysteresis, capped ejection and a panic fallback.›Convolution image filtersgraphics: Separable 2D convolution kernels for blur, sharpen (unsharp mask) and edges with border handlingDead-letter queuedistributed: A side queue for messages that keep failing: after N delivery attempts or a permanent error, park them with the reason so the main queue keeps moving.›Idempotency keysfinance: Client-chosen unique key per logical operation, stored with a request fingerprint and the final response, so retries replay the first result instead of acting twice.›Convolutional codes and theViterbi decodersignal-processing: Streaming error-correcting code: each output bit is a parity of the last K input bits; the Viterbi decoder finds the most likely path through a 2^(K-1)-state trellis.›Rolling hashdata-structures: Rabin-Karp polynomial rolling hashes and winnowing for substring fingerprints and document matchingSwiss tabledata-structures: Open-addressing hash table that filters 8-16 slots at once with 1-byte hash tags and SIMD, giving fast lookups at 87.5 % load.›Byte-pair encoding (BPE)tokenizationmachine-learning: Learn a subword vocabulary by repeatedly merging the most frequent adjacent pair; byte-level BPE encodes any input losslessly with 32k-200k tokens.›+ 37 moreTransparent interceptionnetworking: Redirect traffic to a local proxy (iptables TPROXY/REDIRECT, eBPF) without app changesSyscall interceptionsecurity: Intercept syscalls via ptrace, seccomp user notify or a user-space kernelFencing tokensdistributed: A number that grows with every lock grant and is checked by the protected resource, so a paused ex-holder's late write is rejected.›Text normalizationmachine-learning: Rewrite messy text into one canonical form for matchers and models, or into spoken words for speech output (and back), keeping a map to the original offsets.›+ 15 moreEbpfhardware-os: Verified in-kernel programs on hooks (kprobes, XDP, tc) with mapsPtrace process controlhardware-os: Ptrace: attach, read and write registers and memory, single-step, intercept signalsSeccomp bpfsecurity: Syscall filtering with seccomp BPF programs+ 6 more+ 2 more

How it is built

Architecture overview

A social media management platform lets a team plan, publish, monitor and report on many social accounts from one place. It connects each account through that network's own API, stores posts in a calendar, publishes them at the scheduled time, collects the replies, comments and mentions into one shared inbox, listens for brand keywords across public posts, and rolls everything up into analytics. The platform owns almost none of the data; the networks do, and each one has its own authentication, media rules, quotas and webhooks. The one idea that makes it work: put each network behind an adapter with a common contract, and treat every call to a network as unreliable, rate-limited and possibly duplicated. Publishing is a durable job with an idempotency key; inbound content arrives by webhook or polling and is normalised into one event shape; and the expensive part, understanding text at volume, is a pipeline of cheap steps before any model.

Parts:

 team UI ── compose / approve / schedule ──► post store ──► timer (wheel) ──► publish queue
                                                  ▲                               │ lease, rate-limit per account
                                          media pipeline                          ▼
                                  (resize, transcode, per-network spec)     network adapter ──► network API
                                                                                  ▲  │ 429 / 5xx: backoff
   network ──webhook / poll──► ingest ──► normalise ──► dedupe ──► classify ──► shared inbox
                                                           │
   public stream / search ──► query matcher (keywords) ────┴──► listening feed ──► alerts
                                                           │
                              metrics pulls ──► rollups (hour/day) ──► dashboards, reports

How the parts fit together

Account connection

Each profile (a page, a business account, a channel) is connected by OAuth 2 and OpenID Connect: authorisation code flow, scopes asked per feature (publish, read comments, read insights), tokens stored encrypted and refreshed before expiry. The platform is in the middle of a three-way relation: user, platform, network. A user may connect an account a colleague also connected, a token may be revoked at any time by the user in the network's own settings, and a network may change what a scope allows. So the token record has a state (healthy, expiring, needs reconnect), every adapter call can return "token invalid", and that outcome flips the account to "needs reconnect", pauses its scheduled posts and notifies the team. Silent failure here is the most common support ticket of the whole product.

Composer and media

The composer holds one post with per-network variants (text, media, link). Media is prepared once per target spec. Images are resized and re-encoded to the network's accepted sizes and aspect ratios (Image resampling filters gives the quality choices: shrink with an area-aware or Lanczos kernel, not nearest-neighbour). Videos are transcoded to the container, codec, length and size each network accepts, which is a small Video transcoding ladder with a different top rung per network. The contract with the publisher is a media handle (stored object, checksum, derived renditions), not a URL that can change under it. Links are cleaned with URL normalization, then optionally rewritten to a short tracked link; open-and-click-tracking (no page yet) is the redirect that counts a click and forwards, with the same caveat as in email: bots and link previews also fetch links, so a click count needs bot filtering.

Approval

Larger teams want a rule that a post by an intern needs sign-off before it goes out. This is dual-control-approval (no page yet) in a lightweight form: a post carries a state (draft, in review, approved, scheduled), an approver cannot be its author, and any edit after approval returns it to review. The scheduler only picks up posts in the scheduled state, so the rule cannot be bypassed by timing.

Scheduler and publisher

This is the heart of the product, and it is a Durable job queue: a persisted task per post and per network, leased by a worker for a visibility timeout, acknowledged on success, retried on failure. Hierarchical timing wheel is the in-memory index of "which jobs become due in the next minutes", with the database as the truth; a calendar of scheduled posts is far larger than what is due now.

Publishing is a multi-step call on most networks. Instagram's content publishing flow, for example, is documented as creating a media container first and publishing it afterwards (Meta, Instagram Platform content publishing), which means a crash between the two steps leaves a created but unpublished container. The job must therefore be written as resumable steps: store the container id after step one, and on retry continue from it instead of starting again.

Duplicates are the failure to design out. A network call can succeed on the network's side while the response is lost, and the retry then creates a second post. Where the API offers an idempotency mechanism, use it: Mastodon's status endpoint accepts an Idempotency-Key header to prevent duplicate submissions, and the key is stored for up to an hour (Mastodon docs). Where it does not, the adapter writes a "publishing" marker before the call and, on a retry after an unknown outcome, first looks the post up on the account's timeline by a token embedded in the text or metadata before posting again, or hands the case to a human.

Limits are per app, per user and per endpoint, and they differ by network and plan. The X API documents per-endpoint rate limits with a time window and the x-rate-limit response headers, and answers 429 when exceeded (X API rate limits). The adapter reads such headers into a per-account state, and Distributed rate limiting keeps the count consistent when many workers publish for the same account; a worker that is told to wait releases the job back with a delay computed by Exponential backoff with jitter. Priority matters: a post that is due now outranks a metrics pull, so give the two their own budgets.

Inbound events

Comments, replies, direct messages and mentions come in by two routes. Where the network offers webhooks, it calls the platform; the receiving side of Webhook delivery applies: verify the signature (Meta documents signed webhook payloads; see its webhooks guide), answer 2xx quickly, put the payload on a queue and process later, and be idempotent because the network will redeliver. Where it does not, or when webhooks are not reliable enough, the platform polls with a stored cursor per account, and a periodic reconciliation pull closes gaps left by lost webhooks. The contract with the next stage is one normalised event (network, account, thread id, author, text, media, timestamp, raw payload reference), so everything downstream is network-agnostic.

Understanding

A shared inbox is only useful if it is sorted. The pipeline is cheap first:

  • Language identification routes a message to the right team and models and avoids classifying Portuguese with an English model.
  • Text classification assigns labels: question, complaint, praise, spam, urgent. Start with rules and a linear model on a few thousand labelled messages; use a language model for the labels where wording is ambiguous.
  • Named entity recognition finds products, people and places so a message can be linked to a campaign or a product line.
  • Near-duplicate detection with MinHash LSH clusters copy-pasted spam and the same complaint posted by many people, so the team sees one cluster with a count instead of fifty rows.

Each step returns a label with a confidence; low-confidence items are shown unlabelled instead of mislabelled, and corrections by the team become training data.

Listening

Social listening is the reverse of search: instead of one query against many documents, there are many stored queries (every customer's brand terms and competitor names, with AND/OR/NOT, phrases and exclusions) and one stream of incoming posts. A plain loop over all queries per post is too slow at stream rates. boolean-expression-indexing (no page yet) indexes the queries so each post only evaluates those whose required terms it contains; Aho-Corasick multi-pattern matching finds all the fixed phrases of all queries in one pass over the text; and an Inverted index over stored posts answers the opposite direction, a new query run over history. The contract: a match event (query id, post id, matched spans) written to the listening feed, with spam and near-duplicates filtered before it is counted. Public stream access depends on what each network allows through its API terms, so the source of the stream is a business and legal question before it is a technical one.

Analytics

Reach, impressions, engagement and follower counts are pulled from each network on a schedule and stored as counters per post and account. Rollup aggregation folds raw samples into hourly and daily partial aggregates, so a quarter-long report reads a few hundred rows per account. Time-series anomaly detection turns the same series into alerts ("mentions three times the usual for this hour"). Ranking "what is trending" or "best posts of the week" needs a recency weight: time-decay-scoring (no page yet) discounts older engagement so last week's hit does not outrank today's. Note that network metrics are revised after the fact (late-counted views, deleted spam), so rollups should be re-pulled for a trailing window instead of treated as final.

Operations

The post store (drafts, approvals, schedule, publish state) is what the team trusts to publish at 9:00, so it is replicated with Primary-backup replication: a failover must not lose a scheduled post or forget that one has already gone out.

Point-in-time recovery serves the team that deletes a whole campaign or has a bulk reschedule go wrong: the post store is restored to the minute before, and the publish state is reconciled against what the networks really show, so nothing is published twice.

The scheduler, the publish workers, the network adapters, the ingest workers and the media workers run under Process supervision; a publisher that dies after the network accepted a post but before the record is written is restarted and finds the post by its idempotency key instead of posting again.

A deploy uses Graceful draining: a publish worker finishes the network call it has started and records the network's post id before exiting, and the timer hands its due posts over, so a release at 8:59 does not delay or duplicate the 9:00 posts.

The scheduler, the adapters that hold account tokens, the media pipeline and the inbox service call each other over Mutual TLS, since only the adapters should ever see network tokens, and only services with a certificate may ask them to publish.

A scheduled post is judged by how close to its time it goes out, so the delay between scheduled time and network acceptance, and the time from a comment on a network to the shared inbox, are recorded as an hdr-histogram (no page yet) per network with percentiles; the tail shows the network that is rate-limiting us.

The scheduler and the publish retries are tested with Deterministic simulation testing: a simulated clock and network time out, return 429 and accept a post while the reply is lost, run daylight-saving changes and crash workers mid-publish, and the check is that every scheduled post is published exactly once. Failures replay from their seed.

The webhook payload decoders, the URL normaliser and the keyword-expression parser read text from networks and users, so they run under Coverage-guided fuzzing with mutated payloads and queries, keeping every input that reaches new code.

Data and control flow

Publishing one scheduled post:

  1. The composer saves the post with per-network variants; media jobs prepare renditions; the state moves draft → (in review) → scheduled.
  2. A timer marks the job due; a worker leases it and checks the account's token state and rate budget. If the budget is empty, it releases the job with a delay.
  3. The adapter calls the network (upload media, create container, publish), storing each intermediate id; on a 429 or 5xx the job is retried with jittered backoff.
  4. On success the network's post id is stored and the first metrics pull is scheduled; on a permanent error (content rejected, token invalid) the post moves to failed with the reason shown to the user. Time goes to media upload and the network's own processing, not to the platform's code.

One inbound comment:

  1. The network's webhook arrives; the signature is verified, the raw payload is stored and a 2xx is returned.
  2. A worker normalises it into an event, drops duplicates by network event id, and links it to the post and thread.
  3. Language, labels, entities and a duplicate cluster are attached; spam is hidden by rule.
  4. The event lands in the inbox with an assignee rule (by label, by account); an alert fires if the label is urgent. Typically the whole path should be seconds, and the pull that reconciles missed webhooks runs behind it.

Scaling

In the order the limits bite:

  1. Network quotas. The first wall is the provider's rate limit per app and per user, not the platform's servers. Levers: webhooks instead of polling, conditional and incremental pulls, shared per-account budgets, queueing by priority.
  2. Media processing. Video transcoding dominates compute and storage. Levers: transcode once per target spec, cache renditions by checksum, skip work when the original already fits the spec.
  3. Timer and job volume. A burst of posts scheduled for "9:00 Monday" hits one minute. Levers: spread executions by a few seconds of jitter inside the minute, shard the job table by account, lease in batches.
  4. Text understanding at stream volume. Levers: language filter first, rules before models, small models on CPU, batch inference for the heavy ones, sample low-value streams.
  5. Listening matching. Levers: index the queries, not the posts; shard the query set by term; drop common words from the required terms.
  6. Analytics storage. Levers: rollups at several granularities, retention per tier, partitioned time series.

Failure modes

FailureSymptomCauseFix
Duplicate postthe same post appears twice on a profileretry after a lost responseidempotency key where offered, "publishing" marker plus lookup before retry
Half-published posta media container or draft exists but no postcrash between create and publish stepsstore intermediate ids, resume from the last completed step
Silent token lossscheduled posts fail days lateruser revoked access or password change expired the tokentoken state machine, alert on first auth error, pause the queue, ask to reconnect
Rate-limit stormmany 429s, long delaysworkers ignore shared budgets or retry in syncread limit headers, shared limiter, backoff with jitter
Rejected mediathe network refuses the uploadwrong size, codec, length or aspect ratio for that networkper-network spec check before upload, show the exact reason
Lost webhooksinbox is missing commentsendpoint was down, signature check failing, network dropped eventsreturn 2xx fast, reconcile by polling a trailing window
Mislabelled inboxcomplaints marked as praise, sarcasm lostmodel weak on a language or toneshow confidence, route low confidence to humans, learn from corrections
Wrong-time postsposts go out an hour offtime zone and daylight-saving error in the calendarstore absolute instants plus the zone the user chose
Metrics that movedashboard numbers change after the factnetwork revises insightsre-pull a trailing window, label recent numbers as provisional

Real implementations

No open-source project was found for this page that covers publishing, a shared inbox, listening and analytics together; the open projects below cover the publishing and scheduling core. Commercial tools such as Hootsuite and Buffer are not listed because none of their internals was verified.

namewhat it isrepolicencenotes
Postizopen-source social media scheduling toolgitroomhq/postiz-appAGPL-3.0multi-network scheduling, self-hosted
Mixpostself-hosted social media scheduling and publishinginovector/mixpostMITschedules, publishes and manages posts on your own server; describes itself as a Buffer alternative
Temporaldurable workflow enginetemporalio/temporalMITone way to run resumable multi-step publish jobs
libvipsimage processing librarylibvips/libvipsLGPL-2.1fast resize and re-encode for media preparation
FFmpegaudio and video toolingffmpeg.orgsee sitetranscoding to per-network specs

Sources

Similar systems

Share the most building blocks with this one.