Back to Knowledege base

A common cause of Xi-Text and Xi-Batch issues: Shared memory segment exhaustion.

Symptoms appear as:

  • Scheduler fails to start
  • "Cannot allocate memory" errors
  • Jobs or printers suddenly stop being created
  • System becomes unresponsive to new operations

Why Shared Memory is Fixed

Xi-Text and Xi-Batch use System V IPC shared memory segments. These segments have fixed sizes that must be allocated when the scheduler starts.

Historical constraint:

In the 1980s-1990s when Xi-Text and Xi-Batch were developed, memory was expensive and scarce. Systems needed to carefully manage memory allocation. Once allocated, shared memory segments could not be easily expanded, especially if other applications had consumed available memory.

Today's systems have gigabytes of RAM. The old constraints are no longer mandatory, but the architecture remains to ensure that the software is fast, efficient and can still run on a variety of platforms including embedded, mobile and IoT devices.

What Gets Stored in Shared Memory

Xi-Text:

  • Job queue entries
  • Printer definitions
  • Buffer space for communications

Xi-Batch:

  • Job queue entries
  • Variable definitions
  • Buffer space for communications

When you run out:

  • Cannot add more jobs to queue
  • Cannot add more printers (Xi-Text)
  • Cannot create more variables (Xi-Batch)
  • Scheduler may crash or hang

Default Allocations

Xi-Text default:

bash

spstart          # Typically 1000 jobs, 50 printers

Xi-Batch default:

bash

btstart          # Typically 1000 jobs, 200 variables

These defaults are far too small for modern production systems.

Setting Appropriate Allocations

Modern systems should allocate generously.

Xi-Text:

bash

spstart 10000 200
#       ^jobs ^printers

Xi-Batch:

bash

btstart -j 10000 -v 5000
#       ^jobs    ^variables

Why allocate more than you need?

On modern systems with gigabytes of RAM, overcommitting shared memory has negligible impact. The memory footprint is minimal compared to total system resources.

Better to allocate too much than too little.

Calculating Your Needs

Xi-Text:

Jobs needed = Peak queue size × 1.5
Printers needed = Number of printers × 1.2

Example calculation:

Peak queue: 2000 jobs
Allocation: 2000 × 1.5 = 3000 jobs minimum
Recommended: 5000 jobs (generous buffer)

Printers: 50
Allocation: 50 × 1.2 = 60 minimum
Recommended: 100 (generous buffer)

Xi-Batch:

Jobs needed = Maximum jobs in schedule × 1.5
Variables needed = Total variables × 2.0

Example calculation:

Maximum jobs: 500
Allocation: 500 × 1.5 = 750 minimum
Recommended: 2000 (generous buffer)

Variables: 150
Allocation: 150 × 2.0 = 300 minimum
Recommended: 1000 (generous buffer)

Recommended Modern Allocations

Small installation:

bash

# Xi-Text
spstart 5000 100

# Xi-Batch
btstart -j 5000 -v 2000

Medium installation:

bash

# Xi-Text
spstart 10000 200

# Xi-Batch
btstart -j 10000 -v 5000

Large installation:

bash

# Xi-Text
spstart 50000 500

# Xi-Batch
btstart -j 50000 -v 10000

Very large installation:

bash

# Xi-Text
spstart 100000 1000

# Xi-Batch
btstart -j 100000 -v 20000

Memory Impact

Typical memory usage per entry:

  • Job: ~2-4 KB
  • Printer: ~1-2 KB
  • Variable: ~1-2 KB

Example: Large allocation memory footprint:

Xi-Batch with 50,000 jobs and 10,000 variables:
  Jobs: 50,000 × 3 KB = 150 MB
  Variables: 10,000 × 2 KB = 20 MB
  Total: ~170 MB

On a system with 8 GB RAM, this is 2% of available memory.

On a system with 64 GB RAM, this is trivial.

Updating Startup Scripts

Find your startup script:

bash

# Common locations
/etc/init.d/xitext
/etc/init.d/xibatch
/usr/lib/systemd/system/xitext.service
/usr/lib/systemd/system/xibatch.service

Xi-Text init script:

bash

#!/bin/bash
# /etc/init.d/xitext

case "$1" in
  start)
    echo "Starting Xi-Text..."
    /usr/bin/spstart 10000 200
    ;;
  stop)
    echo "Stopping Xi-Text..."
    /usr/bin/sstop
    ;;
esac

Xi-Batch init script:

bash

#!/bin/bash
# /etc/init.d/xibatch

case "$1" in
  start)
    echo "Starting Xi-Batch..."
    /usr/bin/btstart -j 10000 -v 5000
    ;;
  stop)
    echo "Stopping Xi-Batch..."
    /usr/bin/btquit -y
    ;;
esac

Systemd service files:

ini

# /usr/lib/systemd/system/xitext.service
[Unit]
Description=Xi-Text Print Spooler
After=network.target

[Service]
Type=forking
ExecStart=/usr/bin/spstart 10000 200
ExecStop=/usr/bin/sstop
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target

ini

# /usr/lib/systemd/system/xibatch.service
[Unit]
Description=Xi-Batch Job Scheduler
After=network.target

[Service]
Type=forking
ExecStart=/usr/bin/btstart -j 10000 -v 5000
ExecStop=/usr/bin/btquit -y
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target

Verifying Current Allocation

Check running process:

bash

# Xi-Text - check startup command
ps aux | grep spstart

# Xi-Batch - check startup command  
ps aux | grep btstart

Look at IPC segments:

bash

# Show shared memory segments
ipcs -m | grep spooler    # Xi-Text
ipcs -m | grep batch      # Xi-Batch

Check scheduler log:

bash

# Xi-Text
grep -i "jobs\|printers" /usr/spool/spd/spshed_reps | head

# Xi-Batch
grep -i "jobs\|variables" /usr/spool/batch/btsched_reps | head

When to Increase Allocation

Warning signs:

  • Seeing errors about memory allocation
  • Jobs mysteriously failing to submit
  • Queue suddenly stops accepting new jobs
  • System becomes sluggish

Check current usage:

bash

# Xi-Text - count current jobs
sqlist | wc -l

# Xi-Batch - count current jobs and variables
btjlist | wc -l
btvlist | wc -l

If approaching 80% of allocated space, increase allocation.

Applying New Allocations

Requires scheduler restart:

bash

# Xi-Text
sstop
spstart 20000 300

# Xi-Batch
btquit -y
btstart -j 20000 -v 10000

Cannot change allocations while running. Must stop and restart with new values.

Plan for scheduled maintenance window.

Best Practices

Always allocate generously:

Memory is cheap. Exhausting shared memory causes production outages.

Use round numbers:

Easier to remember and document:

  • 5000, 10000, 20000, 50000
  • Not 3742, 8391

Document your allocation:

Record why you chose specific numbers:

bash

# Allocated 10,000 jobs for peak load of 6,000 + 60% buffer
# Allocated 5,000 variables for 2,000 in use + 150% buffer
btstart -j 10000 -v 5000

Review quarterly:

Monitor actual usage and adjust allocations as workload grows.

Default to larger allocations:

Would you rather:

  • Allocate 50,000 slots and use 5,000 (no problem)
  • Allocate 5,000 slots and need 50,000 (production outage)

On modern systems, choose the safe option.

Common Misconceptions

"Won't allocating too much waste memory?"

No. On systems with 8+ GB RAM, even very large allocations (100,000 jobs) use less than 1% of total memory.

"Can't we expand shared memory dynamically?"

Xi-Text and Xi-Batch attempt this, but it often fails if other applications have consumed available shared memory. Better to allocate correctly at startup.

"Our system is small, we don't need much."

Systems grow. Allocate for future growth. The overhead is negligible.

Quick Reference

Recommended starting points:

bash

# Xi-Text - small site
spstart 10000 200

# Xi-Text - large site
spstart 50000 500

# Xi-Batch - small site
btstart -j 10000 -v 5000

# Xi-Batch - large site
btstart -j 50000 -v 10000

Check current allocation:

bash

ps aux | grep "spstart\|btstart"

Apply new allocation:

bash

# Stop, restart with new values
# Xi-Text
sstop && spstart 20000 300

# Xi-Batch
btquit -y && btstart -j 20000 -v 8000

Update startup script permanently. Otherwise allocations reset on next reboot.

Bottom line: On modern systems with abundant RAM, generously allocate shared memory. The tiny memory overhead is insignificant compared to the risk of shared memory exhaustion. When in doubt, allocate more.

Using emerglic for Emergency 7-Day Licences
Temporary licensing when validation keys become corrupted or unavailable