Nexal Restarts
A scheduled server restart manager with player warnings, configurable notifications, and graceful shutdown handling for Minecraft Paper and Spigot servers.
Requirements
Nexal Restarts stops the server (Bukkit.shutdown()); it does not start it again. The server comes back only when something restarts the process:
- Hosting panels (Pterodactyl, Pelican, most Minecraft hosts): turn on the panel's auto-restart / crash detection, or schedule a start after the stop. Most panels restart a server that stops on its own.
- Your own machine: run the server in a loop script or as a service that restarts on exit, e.g.
while true; do java -jar server.jar; sleep 5; done, or a systemd unit withRestart=always.
Features
- Cron-based Scheduled Restarts - Flexible scheduling using cron expressions with timezone support
- Configurable Warning Intervals - Alerts at any times before a restart (30min, 10min, 5min, 1min, 30s by default)
- Multi-channel Notifications - Chat messages, titles, subtitles, actionbar and sounds, each with its own toggle
- Live Final Countdown - Actionbar countdown with title flashes during the last 10 seconds
- Graceful Shutdown - Run commands globally, per world and per player, then kick players with a message
- Manual Restarts -
/restart admin in 5mschedules a restart with the usual warnings - Instant Restart -
/restart admin nowrestarts right away - Cancel Restarts -
/restart admin cancelcancels a manual restart, or skips a scheduled one; the schedule resumes with the next occurrence - Admin GUI -
/restart adminopens a hub to schedule, cancel or trigger restarts, see the status, and change the settings (schedule, cron, timezone, warning intervals, notifications) - Restart Status -
/restart statusshows the next restart time - PlaceholderAPI Support - Placeholders for the next restart, countdown and status
- Hot-reload Configuration - Config and messages reload when saved, keeping any pending restart
- Proxy Sync - Share schedules, restarts and cancels across servers behind BungeeCord or Velocity
- Server Exemption - Mark servers as exempt from receiving sync commands (master/slave setup)
Technologies
- Paper/Spigot API 1.20.1+ - Minecraft server API
- nexal-core - Help menu and license check
- Utilizer - Configuration, messages, GUIs, tasks
- ACF - Annotation Command Framework
- cron4j - Cron expression parsing
- PlaceholderAPI - Placeholder integration (optional)
Commands
Player Commands
| Command | Description | Permission |
|---|---|---|
/restart or /restart help | Show help information | None |
/restart status | View next restart time | nexalrestarts.status |
Admin Commands
| Command | Description | Permission |
|---|---|---|
/restart admin | Open the admin GUI (shows the admin help in the console) | nexalrestarts.admin |
/restart admin help [page] | Show the admin commands | nexalrestarts.admin |
/restart admin in \<time> | Schedule a restart (e.g. 5m, 1h) | nexalrestarts.restart |
/restart admin now | Restart immediately | nexalrestarts.restart.now |
/restart admin cancel | Cancel the pending restart | nexalrestarts.cancel |
Proxy Sync Commands
| Command | Description | Permission |
|---|---|---|
/restart admin sync | Send this server's schedule (cron, timezone, on/off) to all other servers | nexalrestarts.sync |
/restart admin sync restart <time|now> | Restart all servers, this one included (at least 5 seconds, or now) | nexalrestarts.sync |
/restart admin sync cancel | Cancel the restart on all servers, this one included | nexalrestarts.sync |
/restart has the aliases /nexalrestart and /ar. There is no reload command: config.yml and messages.yml reload by themselves when saved.
Time Format Examples
30s- 30 seconds5m- 5 minutes1h- 1 hour1d- 1 day
Pending and cancelled restarts
A restart is pending when it was scheduled with /restart admin in, or when a scheduled restart is within its warning window (by default 30 minutes away). /restart admin cancel cancels a pending manual restart and skips a pending scheduled one; the schedule carries on with the following occurrence.
Admin GUI
/restart admin opens the hub:
- Configuration (
nexalrestarts.config): the settings screen- Toggles for the schedule, final countdown, kicking players, chat, titles, actionbar, sounds and proxy sync
- Cron Expression: left click cycles through common schedules, right click to type your own in chat
- Timezone: left click cycles through common timezones, right click to type your own in chat
- Warning Intervals: turn each warning time on or off
- Plugin Info: schedule, next restart, pending restart, proxy sync and version
- Schedule Restart (
nexalrestarts.restart): restart in 1m, 5m, 10m, 15m, 30m, 1h or 2h - Cancel Restart (
nexalrestarts.cancel): cancel the pending restart - Restart Now (
nexalrestarts.restart.now): shift left click to restart right away
Permissions
| Permission | Description | Default |
|---|---|---|
nexalrestarts.status | View restart status | true |
nexalrestarts.admin | Admin GUI and admin help; grants all the admin permissions below | op |
nexalrestarts.restart | Schedule manual restarts | op |
nexalrestarts.restart.now | Instant restart | op |
nexalrestarts.cancel | Cancel restarts | op |
nexalrestarts.sync | Sync across proxy servers | op |
nexalrestarts.config | Change the settings in the admin GUI | op |
nexalrestarts.* | All permissions | op |
Placeholders
Requires PlaceholderAPI.
| Placeholder | Description |
|---|---|
%nexalrestarts_next% | Next restart time (formatted), or None |
%nexalrestarts_countdown% | Time until restart (e.g. "5m 30s"), or None |
%nexalrestarts_seconds% | Raw seconds until restart |
%nexalrestarts_pending% | "true" while a restart is pending, else "false" |
%nexalrestarts_scheduled% | Same as %nexalrestarts_pending% |
%nexalrestarts_enabled% | "true" if any restart is coming up |
Configuration
config.yml
# Cron schedule for automatic restarts
schedule:
enabled: true
# Timezone for cron schedule (default: Europe/Athens)
# Find your timezone: https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
timezone: "Europe/Athens"
# Examples:
# "0 */6 * * *" - Every 6 hours
# "0 0,12 * * *" - Twice daily (midnight and noon)
# "0 4 * * *" - Daily at 4:00 AM
cron: "0 */6 * * *"
# Warning intervals in seconds before restart. Each uses its own
# warnings.\<seconds> entry in messages.yml, or warnings.default without one.
warnings:
- 1800 # 30 minutes
- 600 # 10 minutes
- 300 # 5 minutes
- 60 # 1 minute
- 30 # 30 seconds
# Final countdown (last 10 seconds). When off, the restart still happens on time.
final-countdown:
enabled: true
title-at: [10, 5, 4, 3, 2, 1]
# Notification channels
notifications:
chat: true
title: true
actionbar: true
sound: true
# Graceful shutdown
shutdown:
kick-players: true
commands:
global:
- "save-all"
per-world: [] # %world% placeholder
per-player: [] # %player% placeholder
# How times are shown in messages and placeholders.
# A part that is 0 is left out (1h instead of 1h 0m).
time-format:
hours: "%hours%h %minutes%m"
minutes: "%minutes%m %seconds%s"
seconds: "%seconds%s"
messages.yml
Every message is customizable in MiniMessage format (<gradient:#E67E22:#EB984E>, \<bold>, \<white>), and can carry:
message(one line or a list),title,subtitle,actionbarsound, plusvolumeandpitchfor the warnings and the countdownfade-in,stay,fade-outfor titles
The colors are listed at the top of the file for find-and-replace. Warnings are keyed by their seconds (warnings.600); any interval without its own entry uses warnings.default, with %time% as the time left.
When an update brings new messages, they are added to your messages.yml on startup; entries you already have are left as they are. To get changes to existing messages (such as new sounds), rename your messages.yml and let the plugin generate a fresh one.
Cron Expression Guide
Cron expressions follow the format: minute hour day-of-month month day-of-week
| Field | Values |
|---|---|
| Minute | 0-59 |
| Hour | 0-23 |
| Day of Month | 1-31 |
| Month | 1-12 |
| Day of Week | 0-6 (0 = Sunday) |
Common Examples
| Expression | Description |
|---|---|
0 */6 * * * | Every 6 hours |
0 0,12 * * * | Midnight and noon |
0 4 * * * | Daily at 4:00 AM |
0 3 * * 0 | Every Sunday at 3:00 AM |
30 */4 * * * | Every 4 hours at :30 |
0 0 * * 1-5 | Weekdays at midnight |
Installation
- Download the plugin JAR
- Place in
/pluginsfolder - Make sure your host or start script restarts the server when it stops (see Requirements)
- Start/restart server
- Set your schedule with
/restart admin→ Configuration, or inconfig.yml - Customize messages in
messages.yml; changes apply when you save the file
Proxy Sync
Synchronize restart schedules, restarts and cancels across multiple servers connected via BungeeCord or Velocity.
Configuration
proxy-sync:
enabled: true
server-name: "survival" # Unique name for this server
secret: "change-me-to-a-long-random-value" # The same on every server
exempt: false # Set true to ignore incoming syncs (master server)
receive:
schedule: true # Accept schedule syncs
restart: true # Accept restart commands
cancel: true # Accept cancel commands
auto-sync-on-reload: false
How it works
- Enable proxy sync on all servers
- Give each server a unique
server-name - Set the same
secreton every server. Sync stays off while it is empty - Use
/restart admin syncto send your schedule (cron, timezone and on/off) to all servers; they save it to theirconfig.yml - Use
/restart admin sync restart 5mto restart all servers, including the one you run it on (/restart admin sync cancelcancels it everywhere) - Set
exempt: trueon master servers that shouldn't receive syncs
Messages travel through the proxy's BungeeCord plugin channel (Forward), which players cannot send on, and each one is signed with the secret. On Velocity, keep bungee-plugin-message-channel = true in velocity.toml (the default). Plugin messages always travel through a player, so the sending server needs a player online, and only servers with a player online receive the message. Online staff with nexalrestarts.admin on the receiving servers are told what arrived.