Skip to content

Channel limits

Your plan sets how many channels you can keep connected and active at once. You can see the number, and how many you have used, in Billing → Usage and in the plan card in the sidebar.

What counts

Only active channels count. A paused channel does not.

That is the important part, because it gives you a way out that does not cost anything: if you are at your limit and want to connect something new, pause a channel you are not using right now and the slot is free.

A paused channel is not deleted. It keeps its connection, its history and its past results — it simply does not publish. You can un-pause it at any time, as long as you have room.

When you reach the limit

The connect buttons stop

On the Channels page, adding a channel is disabled and tells you how many you have used. Nothing happens silently — you will not be sent to Instagram or X to authorise something that would then be refused.

Pause one, or upgrade

Pause a channel you are not using to free a slot, or move to a plan with more room. Both take effect immediately.

If you are already over the limit

This can happen if you moved to a smaller plan, or if your channels were connected before the limit was enforced.

Sosyabot brings the workspace back under its plan by pausing the newest channels first — the ones you have been publishing to for the longest are the ones it keeps. It tells you which ones it paused, by name, in a notification and by e-mail.

Nothing is deleted. When you upgrade, the channels it paused come back on their own, oldest first, up to the room your new plan gives you. A channel you paused stays paused, because that was your decision.

TIP

Pausing a channel is always allowed, whatever your plan. Only turning one back on needs a free slot.

For developers

The limit is plan.limits.social_accounts; 999999 is the unlimited sentinel. The count is Accounts.countDocuments({ ...tenantReadScope(owner, workspace), status: { $ne: 0 } }) — the same predicate the channels list uses, so the meter and the screen cannot disagree. Note status: { $ne: 0 } rather than status: 1: accounts connected before the field existed have no status and do publish, so they count.

Enforcement lives in backend/src/services/channelLimit.service.ts rather than in enforceQuota, because an OAuth callback is a stateless provider redirect with no req.workspace for a middleware to read. Five paths call it: the createConnectedAccount choke point, the Listmonk controller, the status-raise in updateAccountStatus, and the connect callbacks that map ChannelLimitError to a redirect or a 403 { code: "CHANNEL_LIMIT_REACHED" }.

Reconciliation runs daily (channel-limit, jobId: channel-limit-daily) and stamps paused_by_limit: true, which is what lets an upgrade un-pause exactly those rows and never one the user paused. Operators can preview and apply it by hand: pnpm --filter sosyabot-backend report:channel-limit, then enforce:channel-limit -- --apply --confirm-channel-limit (manifest-backed, with --rollback).