Skip to main content

General Questions

What is Undying Terminal?

Undying Terminal is a Windows-native persistent terminal solution that keeps SSH sessions alive through network disconnects, laptop sleep, VPN switches, and other interruptions. Unlike traditional SSH, it implements:
  • Automatic reconnection with exponential backoff
  • Sequence-based packet recovery (no data loss)
  • 64MB recovery buffer per direction
  • Keepalive heartbeat (every 5 seconds)

How is this different from SSH?

FeatureUndying TerminalSSH
Session PersistenceSurvives disconnectsDrops immediately
Automatic ReconnectBuilt-inManual only
Packet RecoveryUp to 64MBNone
Port Forwarding PersistenceTunnels surviveDrops with session
Windows NativeConPTY integrationRequires WSL/OpenSSH
Use Undying Terminal when:
  • Working from unstable networks (WiFi, mobile, VPN)
  • Running long processes that can’t be interrupted
  • Frequently switching networks
  • Need persistent port forwarding
Use SSH when:
  • Network is stable
  • Quick one-off commands
  • Need features not yet supported by Undying Terminal

Is this production-ready?

Yes, for persistent terminal sessions on Windows. Stable Features:
  • Session persistence and recovery
  • Port forwarding (forward and reverse)
  • SSH bootstrap
  • Jumphost support
  • Optional encryption (XSalsa20)
Known Limitations:
  • Windows-only

Can I use this on Linux or macOS?

No. Undying Terminal binaries are Windows executables. If you need to use it from a non-Windows machine, the practical options are:
  • Use RDP/Remote Desktop into a Windows machine and run the client there
  • Run a Windows VM and run the client there

What does “undying” mean?

Sessions never die from network issues:
  • Disconnects → Automatic reconnect
  • Laptop sleep → Recovers on wake
  • VPN switch → Seamless transition
  • Network change → Transparent recovery
The terminal stays alive as long as the server process is running.

Installation & Setup

Which Windows version do I need?

Minimum: Windows 10 Build 17763 (October 2018 Update) Reason: ConPTY API introduced in Build 17763. Check your version:
[System.Environment]::OSVersion.Version
Supported:
  • Windows 10 (1809+)
  • Windows 11
  • Windows Server 2019+

Do I need administrator rights?

For basic use: No For some features: Yes
  • Windows Service installation
  • Firewall rule creation (can use --add-firewall)
  • System-wide PATH modification
Recommendation: Install to user directory if no admin access.

How do I install as a Windows service?

# PowerShell (Run as Administrator)

# 1. Install service
sc.exe create UndyingTerminalServer `
  binPath= "C:\Program Files\UndyingTerminal\undying-terminal-server.exe --service" `
  start= auto `
  DisplayName= "Undying Terminal Server"

# 2. Start service
sc.exe start UndyingTerminalServer

# 3. Verify
sc.exe query UndyingTerminalServer
See Windows Service Guide for details.

Can I run multiple servers on one machine?

Yes, using different ports and pipe names:
# Server 1 (default)
./undying-terminal-server.exe

# Server 2 (custom port and pipe)
$env:UT_PIPE_NAME = "\\\\.\\pipe\\undying-terminal-2023"
./undying-terminal-server.exe --port 2023
Each terminal must use matching UT_PIPE_NAME to connect to the correct server.

Connection & Usage

Why won’t my client connect?

Checklist:
  1. Server running?
    netstat -ano | findstr :2022
    
  2. Correct client ID and passkey?
    • Must match terminal output exactly
    • Passkey is case-sensitive hex string
  3. Firewall blocking?
    # Add firewall rule
    ./undying-terminal-server.exe --add-firewall
    
  4. Network reachable?
    Test-NetConnection -ComputerName <HOST> -Port 2022
    
  5. Encryption mismatch?
    • Server and client must both use same shared_key_hex
    • Or both have no encryption
Debug mode:
$env:UT_DEBUG_HANDSHAKE = 1
./undying-terminal.exe --connect ...

How do I know if my session is alive?

Methods:
  1. Keepalive packets (automatic)
    • Client sends every 5 seconds
    • Server echoes back
    • If 3 missed → triggers reconnect
  2. Send a command:
    # In session
    echo "test"
    
    If output appears, session is alive.
  3. Check server logs (if verbose=true):
    [INFO] Client abc123 connected
    [INFO] Keepalive received from abc123
    

What happens when I disconnect?

Automatic Recovery Process:
  1. Disconnect detected
    • Client notices (socket error or 3 missed keepalives)
    • Server keeps terminal alive
  2. Reconnect attempts
    • Client: Exponential backoff (100ms → 2000ms)
    • Tries until successful
  3. Recovery handshake
    • Exchange sequence numbers
    • Resend missed packets (up to 64MB)
    • Resume normal operation
  4. User experience
    • Session continues where it left off
    • Recent output replayed (catchup)
    • New output streams normally
Active connections (TCP tunnels) are not preserved - applications must reconnect.

Can I reconnect from a different computer?

No, not directly. The client ID is machine-specific. Workaround:
  1. Copy client ID and passkey to new machine
  2. Connect with same credentials
  3. Server treats it as the same session
Security Note: This means anyone with client ID + passkey can hijack your session. Keep credentials secure!

How do I disconnect safely?

Recommended: Close the client terminal window Effect:
  • Client disconnects
  • Server keeps session alive
  • Terminal continues running
  • Can reconnect anytime
NOT Recommended: Exit the shell
# DON'T DO THIS:
exit           # Terminates terminal process
Ctrl+D         # Sends EOF (may exit shell)
Effect:
  • Shell exits
  • Terminal process terminates
  • Session ends
  • Must restart terminal

Security

How secure is the encryption?

Algorithm: XSalsa20 (via libsodium)
Key Size: 256-bit (32 bytes)
Nonce: 24 bytes, auto-incremented per packet
Security Properties:
  • Confidentiality (data is encrypted)
  • No authentication (no MAC/AEAD)
  • Passkey sent in plaintext initially
Recommendation:
  • Enable for internet-facing servers
  • Use strong random keys (not passphrases)
  • Combine with firewall rules
  • Consider VPN for highly sensitive environments
Not suitable for:
  • Government/military secrets
  • Compliance-driven environments (use VPN)
  • Scenarios requiring authentication

Should I expose this to the internet?

Short answer: Only with encryption enabled and strong firewall rules. Best Practices:
  1. Enable encryption:
    # ut.cfg
    shared_key_hex=<random-32-byte-hex>
    
  2. Firewall rules:
    • Restrict by source IP if possible
    • Use non-standard port
    • Monitor failed connection attempts
  3. Strong passkeys:
    • Use long random hex strings
    • Rotate periodically
    • Don’t share
  4. Consider VPN:
    • For sensitive environments
    • Adds defense-in-depth
    • Better authentication
Safer Alternative: VPN + localhost binding
bind_ip=127.0.0.1  # Only accessible via VPN

How do I rotate encryption keys?

Process:
  1. Generate new key:
    $bytes = New-Object byte[] 32
    [Security.Cryptography.RNGCryptoServiceProvider]::Create().GetBytes($bytes)
    $newKey = -join ($bytes | ForEach-Object { $_.ToString("x2") })
    
  2. Update server config:
    # ut.cfg
    shared_key_hex=<NEW_KEY>
    
  3. Restart server:
    Restart-Service UndyingTerminalServer
    # OR
    # Kill and restart manually
    
  4. Update all clients:
    • Existing sessions will disconnect
    • Clients must use new key to reconnect
Recommendation: Schedule during maintenance window.

Performance

What’s the latency overhead?

Typical: 1-2ms additional latency Breakdown:
  • Framing: ~0.5ms
  • Sequence tracking: ~0.5ms
  • Encryption (if enabled): ~0.5-1ms
  • Network: (varies)
For comparison:
  • SSH: 0.5-1ms overhead
  • Mosh: 1-3ms (with prediction)
Impact: Imperceptible for interactive terminal use (<5ms is instant to humans).

How much bandwidth does it use?

Idle session:
  • Keepalive: ~200 bytes every 5 seconds
  • ~40 bytes/second (~320 bps)
Active session:
  • Same as raw terminal output
  • No compression (sent as-is)
Port forwarding:
  • Same as direct TCP connection
  • No additional overhead
Example: Streaming npm run dev logs at 10KB/s = 10KB/s bandwidth (no overhead).

How many concurrent sessions can I run?

Typical hardware (4-core, 8GB RAM):
  • ~1000 concurrent sessions
  • Limited by:
    • Thread count (1 thread per client + terminal)
    • Memory (~5MB per session)
    • Network bandwidth
Production deployment:
  • Monitor memory usage
  • Scale vertically (more RAM/CPU)
  • Not designed for horizontal scaling
Bottleneck: Usually memory (5MB × 1000 = 5GB)

Troubleshooting

Server won’t start - port already in use

Error: bind: address already in use Find what’s using the port:
netstat -ano | findstr :2022
# Note the PID, then:
tasklist | findstr <PID>
Solutions:
  1. Change port in config:
    port=2023
    
  2. Kill conflicting process:
    Stop-Process -Id <PID> -Force
    
  3. Use command-line override:
    ./undying-terminal-server.exe --port 2023
    

Session is very slow

Possible causes:
  1. Network latency:
    ping <server-host>
    # Check latency
    
  2. Packet loss:
    • High packet loss triggers frequent catchup
    • Check network quality
  3. Large recovery buffer:
    • Replaying 64MB on reconnect takes time
    • Wait for catchup to complete
  4. Server overload:
    • Check CPU/memory on server
    • Reduce concurrent sessions
Debug:
$env:UT_DEBUG_HANDSHAKE = 1
# Watch for excessive catchup messages

Terminal output is garbled

Causes:
  1. Terminal resize mismatch:
    • Resize client window
    • Terminal should auto-adjust
  2. Shell encoding issues:
    • Ensure UTF-8 encoding
    • Check $OutputEncoding in PowerShell
  3. ConPTY issues:
    • Restart terminal process
    • Update Windows (ConPTY bugs fixed in newer builds)
Workaround: Clear screen
cls     # CMD
clear   # PowerShell

Advanced Topics

Can I modify the keepalive interval?

Currently: Requires recompile In code (src/ut/Keepalive.cpp):
constexpr auto kKeepaliveInterval = std::chrono::seconds(5);
// Change to desired interval
There is no config file option for this currently.

How does the recovery buffer work?

Mechanism: Each connection maintains:
  • BackedWriter: Last 64MB of sent packets
  • BackedReader: Sequence number tracker
  • Catchup: Resend missed packets on reconnect
Limits:
  • 64MB per direction (128MB total)
  • FIFO queue (oldest packets dropped)
Edge case: If client disconnects for hours and server sends >64MB, some packets are lost. By design (bounded memory).

Can I run the client on Linux?

No. The client is Windows-only.

Roadmap

There is no published roadmap. If you want to propose changes or new features, please open an issue: https://github.com/Microck/UndyingTerminal/issues Community requests: GitHub Issues

How can I contribute?

See Contributing Guide. Ways to help:
  • 🐛 Report bugs
  • 📝 Improve documentation
  • 💻 Submit pull requests
  • 🧪 Test on different Windows versions
  • 💬 Help triage GitHub issues

Getting Help

Where can I get support?

Documentation: https://undyingterminal.mintlify.app/
GitHub Issues: https://github.com/Microck/UndyingTerminal/issues
Before asking:
  1. Check this FAQ
  2. Search existing issues
  3. Enable debug logging ($env:UT_DEBUG_HANDSHAKE=1)
When reporting bugs:
  • Windows version
  • Undying Terminal version
  • Error messages (full output)
  • Steps to reproduce