Skip to main content

Subjects

NATS implements a subject-based messaging system where publishers and subscribers communicate through named channels called subjects. This provides a location-transparent, interest-based communication pattern that automatically routes messages across distributed NATS servers.

What is a Subject?

A subject is a string of characters that forms a name which publishers and subscribers use to find each other. It acts as the address for message routing within NATS. Subjects are case-sensitive and can contain any UTF-8 characters except whitespace, tabs and line breaks. It's a good practice to use alphanumeric characters along with - (dash) and _ (underscore) for readability.

In the animation above, events.data is the subject - it's the named channel that connects the publisher to all subscribers without any direct addressing.

Subject Hierarchies

The . (dot) character creates a subject hierarchy, enabling logical grouping of related subjects. This hierarchical namespace helps organize your messaging architecture:

orders.retail.placed
orders.retail.shipped
orders.retail.returned
orders.wholesale.placed
orders.wholesale.shipped
orders.wholesale.returned

Wildcards

NATS provides two wildcards for flexible subscription patterns. While publishers always send to a fully specified subject, subscribers can use wildcards to receive messages from multiple subjects.

The subscriber with pattern orders.retail.* receives messages from matching subjects (green and blue paths) but not from non-matching subjects (red path). The * wildcard matches exactly one token.

Single Token Wildcard (*)

The * wildcard matches exactly one token. For example:

  • orders.retail.* matches:

    • orders.retail.placed
    • orders.retail.shipped
    • orders.retail.returned
  • orders.*.placed matches:

    • orders.retail.placed
    • orders.wholesale.placed
# Subscribe using single token wildcard.
# Since each sub waits indefinitely, try each sub
# in a different terminal or just repeat the
# publishes for each sub.
nats sub "orders.*.shipped"
nats sub "orders.*.placed"
nats sub "orders.retail.*"

# Publish to specific subjects (use a different terminal)
nats pub orders.wholesale.placed "Order W73737"
nats pub orders.retail.placed "Order R65432"
nats pub orders.wholesale.shipped "Order W73001"
nats pub orders.retail.shipped "Order R65321"

Multi-Token Wildcard (>)

The > wildcard matches one or more tokens and can only appear at the end of a subject. If your domain is like this:

sensor.alarm.smoke                   # unqualified
sensor.alarm.smoke.critical # qualified
sensor.alarm.water
sensor.alarm.water.critical

The > wildcard matches one or more tokens and can only appear at the end of a subject. For example, sensor.> matches all sensor subjects

# Subscribe using single token wildcard.
# Since each sub waits indefinitely, try each sub
# in a different terminal or just repeat the
# publishes for each sub.
nats sub "sensor.alarm.*"
nats sub "sensor.*.*.critical"
nats sub "sensor.>"

# Publish to specific subjects (use a different terminal)
nats pub sensor.alarm.smoke "kitchen,14:22"
nats pub sensor.alarm.smoke.critical "kitchen,14:23"
nats pub sensor.alarm.water "basement,16:42"
nats pub sensor.alarm.water.critical "basement,16:43"

Wildcard Comparison

You can combine wildcards for more complex patterns and compare how * and > wildcards behave differently:

Comparing * (single token) vs > (multiple tokens) wildcards
Subject
sensor.alarm.*
sensor.*.*.critical
sensor.>
sensor.alarm.smoke
✗ (too few tokens)
sensor.alarm.smoke.critical
✗ (too many tokens)
sensor.alarm.water
✗ (too few tokens)
sensor.alarm.water.critical
✗ (too many tokens)

The visualization demonstrates:

  • Single token wildcard *: Matches exactly one token, as in sensor.alarm.* and sensor.*.*.critical
  • Multi-token wildcard >: Matches one or more tokens, as in sensor.>

Subject Naming Conventions

  • Alphanumeric: a-z, A-Z, 0-9
  • Special: - (dash) and _ (underscore)
  • Delimiter: . (dot) for hierarchy

Reserved Characters

  • . (dot) - Used for hierarchy, cannot be part of a token
  • * (asterisk) - Wildcard, cannot be in subject names
  • > (greater than) - Wildcard, cannot be in subject names
  • Whitespace - Not allowed in subjects

Reserved Prefixes

Subjects starting with $ are reserved for system use:

  • $SYS - System subjects
  • $JS - JetStream API subjects
  • $KV - Key-Value store subjects
  • $O - Object Store subjects
  • $SRV - Service API subjects
  • _INBOX - Auto-generated reply subjects

Best Practices

Subject Hierarchy Design

  1. Start general, get specific: Use the first tokens for broad categorization

    app.region.service.entity.action
    myapp.us-east.users.profile.update
  2. Keep it reasonable: Limit to ~16 tokens and under 256 characters total

  3. Be consistent: Establish naming conventions early and stick to them

  4. Plan for wildcards: Design hierarchies that work well with wildcard subscriptions

Performance Considerations

  • Subjects Interest graph is in-memory and dynamic: NATS builds a routing table only for subjects with active subscribers, kept entirely in RAM for fast lookups
  • Subjects are essentially free: Creating new subjects has virtually no overhead - NATS efficiently handles millions of unique subjects.
  • Wildcard matching is optimized: Subscriptions with wildcards (* and >) use efficient trie-based matching.

Security and Filtering

Well-designed subject hierarchies enable:

  • Fine-grained access control per user/account
  • Efficient message filtering in JetStream streams
  • Clean import/export patterns between accounts
  • Logical organization for monitoring and debugging

Location Transparency

One of NATS' key features is location transparency through subject-based addressing:

  • Subscriptions automatically propagate across the NATS cluster
  • Messages route to all interested subscribers regardless of their location
  • No configuration needed for message routing between servers
  • Publishers and subscribers don't need to know about each other's location

Wire Taps and Monitoring

The > wildcard enables powerful monitoring capabilities:

# Monitor all messages in the system (subject to permissions)
nats sub ">"

# Monitor all orders
nats sub "orders.>"

# Monitor specific service communications
nats sub "myservice.>"

Try It Yourself

Experiment with subjects using the NATS CLI:

# Terminal 1: Subscribe with wildcards
nats sub "demo.>"

# Terminal 2: Publish to various subjects
nats pub demo.test "Hello"
nats pub demo.test.nested "Nested message"
nats pub demo.another.topic "Another topic"

Each message published in Terminal 2 will be received by the wildcard subscription in Terminal 1, demonstrating how subject hierarchies and wildcards work together.