Rust port of the Multiplayer Piano server with way better performance than the Node.js version. [Original]
Note: Some genius called my original README "AI slop" so I dumbed it down to their reading level. You're welcome.
2025-11-03.02-55-05.mp4
The Node.js version works fine, but it starts choking at around 1000 concurrent users. This rewrite handles 50k+ connections without breaking a sweat. Plus no garbage collection pauses, which is nice.
Performance differences:
- 3-5x faster message processing
 - ~15MB memory vs ~50MB for Node
 - <1ms latency even under heavy load
 - 500k+ messages/sec throughput
 
All the same features as the original. WebSocket-based real-time piano playing, channels, chat, crown system, bans, the whole deal.
You need Rust 1.70+ from https://rustup.rs/
git clone https://github.com/nyxikitty/mpp-server-rust.git
cd mpp-server-rust
# Sound files are already included, you're good to go
cargo build --releaseDevelopment:
cargo runProduction (much faster):
cargo run --releaseServer runs at http://localhost:8080
Optional .env file:
WS_PORT=8080
NODE_ENV=production
RUST_LOG=mpp_server=info
SALT1=random_string_here
SALT2=another_random_stringThe salts are for hashing client IPs in production. If you don't set NODE_ENV to production, it'll just use random IDs.
Clients connect via WebSocket at ws://localhost:8080/ws and send JSON arrays:
[{"m": "hi"}]
[{"m": "ch", "_id": "lobby"}]
[{"m": "n", "t": 1234567890, "n": [{"n": "a1", "v": 0.5}]}]hi- Connectbye- Disconnect+ls/-ls- Subscribe/unsubscribe from channel listt- Time synca- Chatn- Play notesm- Move cursoruserset- Change name/colorch- Join/create channelchset- Change channel settingschown- Give crown to someonekickban- Ban userunban- Unban userdevices- MIDI device list
src/
├── main.rs       - Axum setup
├── server.rs     - Connection handling
├── handlers.rs   - Message handlers
├── types.rs      - Data structures
└── utils.rs      - Helpers
client/           - HTML/CSS/JS (from original)
Uses Tokio for async, Axum for WebSocket, DashMap for lock-free state, Serde for JSON.
/etc/systemd/system/mpp-server.service:
[Unit]
Description=MPP Server
After=network.target
[Service]
Type=simple
User=mpp
WorkingDirectory=/opt/mpp-server
Environment="RUST_LOG=mpp_server=info"
Environment="NODE_ENV=production"
ExecStart=/opt/mpp-server/target/release/mpp-server
Restart=always
[Install]
WantedBy=multi-user.targetsudo systemctl enable mpp-server
sudo systemctl start mpp-serverserver {
    listen 80;
    server_name mpp.example.com;
    location /ws {
        proxy_pass http://127.0.0.1:8080;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
    location / {
        proxy_pass http://127.0.0.1:8080;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}version: '3.8'
services:
  mpp-server:
    build: .
    ports:
      - "8080:8080"
    environment:
      - NODE_ENV=production
      - RUST_LOG=mpp_server=info
    restart: unless-stoppedDockerfile:
FROM rust:1.75 as builder
WORKDIR /app
COPY Cargo.* ./
COPY src ./src
RUN cargo build --release
FROM debian:bookworm-slim
WORKDIR /app
COPY --from=builder /app/target/release/mpp-server .
COPY client ./client
EXPOSE 8080
CMD ["./mpp-server"]WebSocket won't connect
- Check your firewall
 - Make sure you're using 
ws://nothttp:// - Look at browser console
 
Notes don't play
- Sound files should be in 
client/sounds/ - Check browser console for 404s
 
Memory issues
- Check if the banned users map is getting huge
 - Use 
--releaseflag, debug builds use way more memory 
- Always use 
--releasefor production (it's like 10-100x faster) - Set 
RUST_LOGtoinfoorwarnin production - Increase file descriptor limit: 
ulimit -n 65535 
- tokio - async runtime
 - axum - web framework
 - serde - JSON
 - dashmap - concurrent hashmap
 - tower-http - middleware
 - tracing - logging
 
MIT - same as the original
PRs welcome. Just try to keep it compatible with the Node version's protocol.
Based on the original MPP server
Piano sounds from https://github.com/multiplayerpiano/piano-sounds