Implementing a Social Media Auto-Posting Scheduler
Scheduler — it's not just "queue task". It's content flow management tool: post queue for weeks ahead, visual calendar, frequency limits, priorities, pauses by schedule (night, weekends).
Data Model
CREATE TABLE scheduled_posts (
id SERIAL PRIMARY KEY,
source_type VARCHAR(50), -- 'product', 'promotion', 'article', 'manual'
source_id INTEGER,
channel VARCHAR(30), -- 'vk', 'telegram', 'instagram', 'ok'
scheduled_at TIMESTAMP NOT NULL,
status VARCHAR(20) DEFAULT 'pending', -- pending|processing|sent|failed|cancelled
attempts SMALLINT DEFAULT 0,
last_error TEXT,
external_post_id VARCHAR(100), -- post ID on platform after publishing
content JSONB, -- serialized content (text, media, links)
created_at TIMESTAMP DEFAULT NOW()
);
CREATE INDEX idx_scheduled_posts_fire ON scheduled_posts (scheduled_at, status)
WHERE status = 'pending';
Task Dispatcher
Dispatcher runs every minute via cron (or as daemon with sleep-loop):
def dispatch_pending_posts():
now = datetime.utcnow()
posts = db.query("""
SELECT * FROM scheduled_posts
WHERE status = 'pending'
AND scheduled_at <= %s
ORDER BY scheduled_at ASC
LIMIT 50
FOR UPDATE SKIP LOCKED
""", [now])
for post in posts:
db.execute("UPDATE scheduled_posts SET status='processing' WHERE id=%s", [post.id])
enqueue_post_job(post)
FOR UPDATE SKIP LOCKED — protection from double processing with multiple workers.
Rate Limiting
Each platform has limits:
| Platform | Limit |
|---|---|
| Instagram Graph API | 25 posts/day per account |
| VKontakte | 50 posts/day per group |
| Telegram Bot | ~30 messages/sec per bot |
| Facebook Page | no hard limit, soft throttle |
Before queuing dispatcher checks counters via Redis:
key = f"post_count:{channel}:{date.today().isoformat()}"
count = redis.incr(key)
redis.expire(key, 86400)
if count > DAILY_LIMITS[channel]:
reschedule_to_tomorrow(post)
return
Publishing Time Windows
Channel settings define when posting allowed:
{
"vk": {
"allowed_hours": [9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20],
"allowed_days": [1, 2, 3, 4, 5, 6, 7],
"min_interval_minutes": 30
},
"telegram": {
"allowed_hours": [8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21],
"allowed_days": [1, 2, 3, 4, 5, 6, 7],
"min_interval_minutes": 15
}
}
If post scheduled for night, dispatcher shifts it to nearest allowed window.
Smart Distribution
When smart_schedule option enabled, system doesn't put all posts at same time. Algorithm:
- Takes all posts with
pendingstatus without specific time - Computes available slots in next 7 days accounting for already scheduled
- Evenly distributes posts across slots with minimum interval
Relevant for online stores with hundreds of products — to avoid publishing all at once after catalog import.
Management Interface
In CMS — page "Post Queue" with:
- Table of scheduled posts with filters by channel, status, date
- Buttons "Publish Now", "Reschedule", "Cancel"
- Calendar view (month/week) with drag-and-drop slot moving
- History of sent posts with links to published posts
Implementation Timeline
Scheduler with basic rules and two channels — 6–8 business days. Smart distribution, calendar UI, rate limiting across all platforms — additional 3–5 days.







