Skip to content

Listen vs Poll Mode

Targets can connect to Mantis in two modes, each suited to different network environments.

In both modes, the Tarsus agent registers and sends heartbeats directly to Mandible. The connection mode only changes how commands are delivered for execution: in Poll mode Tarsus polls its assigned Thorax instance for commands, while in Listen mode a Thorax instance connects inbound to push commands.

ModeDirectionBest For
ListenThorax → TarsusRoutable targets, low latency
PollTarsus → ThoraxNAT/firewall, dynamic IPs

In Listen mode, the Tarsus agent runs a gRPC server, and Thorax initiates connections.

  1. Tarsus starts and listens on configured port (default: 9342)
  2. Tarsus registers with Mandible, providing its address
  3. Thorax connects to Tarsus when commands are available
  4. Commands execute immediately upon connection
RequirementDetails
Inbound port9342 (or configured port)
Firewall ruleAllow Thorax IP → Target:9342
DNS/IPTarget must be routable from Thorax
TLSmTLS connection with certificates
AdvantageDescription
Low latencyCommands execute immediately
Real-timeInstant response to deployments
EfficientNo polling overhead
SimpleDirect connection model
DisadvantageDescription
Network exposureRequires inbound access
Firewall rulesMust configure inbound rules
Dynamic IPsProblematic if IP changes
NAT complexityDifficult behind NAT
  • Servers with static IPs
  • Cloud instances with stable DNS
  • Controlled network environments
  • Low-latency requirements
  • On-premises data centers

Tarsus configuration:

# Operating mode: "listen" or "poll"
mode = "listen"
[listen]
# Address to bind to (0.0.0.0 for all interfaces)
address = "0.0.0.0"
# Port to listen on (default: 9342)
port = 9342

In Poll mode, Tarsus initiates all connections to Thorax, polling for commands.

  1. Tarsus registers and heartbeats outbound to Mandible, which assigns a Thorax instance
  2. Tarsus periodically polls its assigned Thorax for pending commands
  3. When commands are available, Tarsus fetches and executes them
  4. Results are sent back to Thorax
RequirementDetails
Outbound accessgRPC (TLS) to Thorax server
Firewall ruleAllow Target → Thorax:50051
DNSThorax must be resolvable
TLSStandard TLS (client certificate optional)
AdvantageDescription
NAT-friendlyWorks behind NAT
Firewall-simpleOnly outbound rules needed
Dynamic IPsWorks with changing IPs
Cloud-nativeIdeal for auto-scaling
DisadvantageDescription
LatencyCommands wait for next poll
OverheadRegular polling requests
DelayPoll interval affects responsiveness
  • Machines behind NAT
  • Cloud instances with dynamic IPs
  • Networks with outbound-only rules
  • Container environments
  • Edge locations

Tarsus configuration:

# Operating mode: "listen" or "poll"
mode = "poll"
[mandible]
# Mandible internal gRPC endpoint used for registration (host:port).
# Mandible assigns a Thorax instance to poll during registration.
# Env: TARSUS__MANDIBLE__ENDPOINT (default localhost:50052)
endpoint = "mandible.example.com:50052"
[poll]
# Polling interval in seconds
interval_secs = 30
# Maximum commands to fetch per poll
max_commands = 10
IntervalLatencyOverheadUse Case
10sLowHighFrequent deployments
30sMediumMediumStandard (default)
60sHigherLowInfrequent deployments
300sVery highVery lowRare updates
AspectListenPoll
LatencyImmediateUp to poll interval
Network directionInbound to targetOutbound from target
Firewall complexityHigherLower
NAT supportPoorExcellent
Dynamic IP supportPoorExcellent
Server loadLowerHigher (polling)
ScalabilityVery highHigh
Deployment responsivenessInstantDelayed
ScenarioRecommended Mode
On-premises server with static IPListen
AWS EC2 with elastic IPListen
Behind corporate firewallPoll
Home/office with dynamic IPPoll
Kubernetes podPoll
Container in DockerPoll (or Listen with port mapping)
Cloud VM without public IPPoll
Load-balanced clusterPoll

You can mix modes in the same environment:

Production Environment:
├── web-prod-01 (Listen) - DMZ with static IP
├── web-prod-02 (Listen) - DMZ with static IP
├── worker-01 (Poll) - Private subnet
└── worker-02 (Poll) - Private subnet

To change a target’s mode:

  1. Update Tarsus configuration
  2. Restart Tarsus agent
  3. Update target in Lens (if needed)
  4. Verify connection

Target shows offline:

  • Check inbound firewall rules
  • Verify Thorax can reach target:port
  • Check TLS certificate validity
  • Review Tarsus logs

Connection refused:

  • Verify Tarsus is running
  • Check port is correct
  • Confirm no other service using port

Target shows offline:

  • Check outbound connectivity
  • Verify Thorax URL is correct
  • Check DNS resolution
  • Review Tarsus logs

High latency:

  • Reduce poll interval
  • Check for network latency
  • Consider switching to Listen mode if possible
  • Expose only to Thorax servers
  • Use mTLS for authentication
  • Rotate certificates regularly
  • Monitor for unauthorized access
  • Use HTTPS only
  • Validate server certificate
  • Use client certificates when possible
  • Monitor polling patterns

Cloud environments often have:

  • Dynamic IPs
  • NAT gateways
  • Restrictive inbound rules

Poll mode works better in these cases.

When milliseconds matter:

  • Real-time deployments
  • Rapid iterations
  • Time-sensitive operations

Track why each target uses its mode:

TargetModeReason
web-prodListenStatic IP in DMZ
worker-prodPollPrivate subnet, no inbound
dev-localPollDeveloper machine, dynamic IP

Consider what happens if:

  • Listen mode: Thorax can’t reach target
  • Poll mode: Target can’t reach Thorax

Have monitoring and alerting in place.