Skip to main content
npayload is launching soon.
npayloadDocs
Guides

Working with channels

Create and configure standard, compacted, and priority channels with retention, privacy, and lifecycle management

Channels are the core routing primitive in npayload. Messages are published to channels, and subscriptions deliver those messages to consumers. This guide covers channel types, configuration, and lifecycle management.

Channel types

npayload supports three channel types, each optimized for different use cases.

The default channel type. Messages are delivered in the order they are published, with fan-out to all matching subscriptions.

const channel = await npayload.channels.create({
  name: 'orders',
  type: 'standard',
});

Best for: event streams, notifications, general messaging.

A key-value channel where only the latest message per key is retained. When a new message is published with an existing key, it replaces the previous one.

const channel = await npayload.channels.create({
  name: 'user-profiles',
  type: 'compacted',
});

// Publish with a key
await npayload.messages.publish('user-profiles', {
  payload: { name: 'Alice', plan: 'pro' },
  compactionKey: 'user_001',
});

// This replaces the previous message for user_001
await npayload.messages.publish('user-profiles', {
  payload: { name: 'Alice', plan: 'enterprise' },
  compactionKey: 'user_001',
});

Best for: configuration state, user profiles, inventory levels, any "current value" pattern.

Messages are delivered in priority order (highest first) rather than publish order. Priority values range from 0 (lowest) to 9 (highest).

const channel = await npayload.channels.create({
  name: 'alerts',
  type: 'priority',
});

await npayload.messages.publish('alerts', {
  payload: { level: 'critical', message: 'System down' },
  priority: 9,
});

Best for: alert systems, task queues with urgency levels, SLA-sensitive workflows.

Channel configuration

Configure retention, size limits, and metadata when creating a channel.

const channel = await npayload.channels.create({
  name: 'audit-log',
  type: 'standard',
  config: {
    retentionDays: 90,
    maxMessageSize: 65536, // bytes
    metadata: {
      team: 'compliance',
      environment: 'production',
    },
  },
});
OptionDefaultDescription
retentionDays30How long messages are stored before automatic deletion
maxMessageSize262144 (256 KB)Maximum payload size in bytes
metadata{}Arbitrary key-value pairs for labelling

Privacy modes

Every channel has a privacy mode that controls how npayload handles message payloads. Set it at creation time.

// Standard: npayload can read and index payloads
const standard = await npayload.channels.create({
  name: 'events',
  type: 'standard',
  privacy: 'standard',
});

// E2E: npayload cannot read payloads (encrypted client-side)
const encrypted = await npayload.channels.create({
  name: 'medical-records',
  type: 'standard',
  privacy: 'e2e',
});

// Hybrid: metadata visible, payload encrypted
const hybrid = await npayload.channels.create({
  name: 'financial-events',
  type: 'standard',
  privacy: 'hybrid',
});

See Encryption and privacy for details on key management and what each mode means for your data.

Privacy mode cannot be changed after a channel is created. Choose carefully based on your data sensitivity requirements.

Listing and searching channels

// List all channels
const channels = await npayload.channels.list();

// List with pagination
const page = await npayload.channels.list({
  limit: 25,
  cursor: 'next_page_cursor',
});

// Get a specific channel by name
const channel = await npayload.channels.get('orders');

Channel lifecycle

Channels move through three states: active, archived, and deleted.

StatePublishSubscribeData
ActiveYesYesRetained per policy
ArchivedNoRead-onlyRetained per policy
DeletedNoNoPurged
// Archive a channel (no new publishes, existing data accessible)
await npayload.channels.archive('old-events');

// Restore an archived channel
await npayload.channels.restore('old-events');

// Permanently delete a channel and all its data
await npayload.channels.delete('old-events');

Deleting a channel permanently removes all messages, subscriptions, and stream data. This action cannot be undone.

Updating a channel

You can update a channel's configuration and metadata after creation. The channel type and privacy mode are immutable.

await npayload.channels.update('orders', {
  config: {
    retentionDays: 60,
    metadata: {
      team: 'fulfilment',
      environment: 'production',
    },
  },
});

Compacted channel patterns

Compacted channels are especially useful for maintaining current state.

// Feature flags: each flag is a key
await npayload.messages.publish('feature-flags', {
  payload: { enabled: true, rolloutPercentage: 50 },
  compactionKey: 'dark-mode',
});

// Read the latest value for a key
const latest = await npayload.channels.getCompactedValue(
  'feature-flags',
  'dark-mode'
);
console.log(latest.payload.enabled); // true

// List all current keys
const snapshot = await npayload.channels.getCompactedSnapshot('feature-flags');
for (const entry of snapshot) {
  console.log(`${entry.key}: ${JSON.stringify(entry.payload)}`);
}

Best practices

  • Use descriptive, lowercase channel names with hyphens: order-events, user-profiles, system-alerts
  • Set retentionDays based on your compliance and debugging needs
  • Use compacted channels instead of external key-value stores when your consumers are already integrated with npayload
  • Archive channels you no longer publish to rather than deleting them, so historical data remains accessible
  • Apply metadata consistently across channels for easier management at scale

Next steps

Was this page helpful?

On this page