Factorio: Server Configuration Guide
Factorio dedicated servers are controlled by three primary JSON files. Understanding which file to edit is the first step in mastering your server environment.
1. server-settings.json
Effect: Immediate (on restart). Controls the server identity, passwords, connectivity, and admin permissions.
2. map-settings.json
Effect: Permanent. Controls simulation rules like biter evolution, pollution spread, and pathfinding costs.
3. map-gen-settings.json
Effect: World-Start only. Controls ore density, water levels, cliff frequency, and terrain types.
Of those three, map-gen-settings.json is the one you cannot revise later without a reset or console commands - ore density, water, cliffs and starting area are fixed the moment the world is generated. To get them right the first time, the Factorio map generator previews and scores several seeds with those knobs exposed in its new Custom mode (per-resource amount, water, trees, cliffs, enemy bases, starting area, peaceful) and hands you the best one as a ready-to-run save.
Common Server Properties
These settings are found in server-settings.json and can be edited without resetting your world.
| Setting | Type | Description |
|---|---|---|
name |
String | The name shown in the server browser. |
game_password |
String | Password required to join the game. |
max_players |
Integer | Limit the number of concurrent connections (0 = unlimited). |
autosave_interval |
Integer | Minutes between automatic saves. |
auto_pause |
Boolean | If true, the game pauses when no players are online. |
allow_commands |
Select | Who can use /c (Options: "true", "false", "admins-only"). |
The complete shipped server-settings.json, with its defaults
Factorio ships server-settings.example.json as its own template, and it documents 28 keys. This is all of them, in the file's order, with the value the example puts there and the file's own comment where it has one. Copy the example, change what you need, leave the rest.
| Key | Type | Shipped value | The file's own note |
|---|---|---|---|
name | string | "Name of the game as it will appear in the game listing" | |
description | string | "Description of the game that will appear in the listing" | |
tags | list | ["game", "tags"] | |
max_players | int | 0 | Maximum number of players allowed, admins can join even a full server. 0 means unlimited. |
visibility | object | {"public": true, "lan": true} | public: Game will be published on the official Factorio matching server. lan: Game will be broadcast on LAN. |
username | string | empty | |
password | string | empty | Your Factorio.com account password, not the join password. |
token | string | empty | Authentication token. May be used instead of 'password' above. |
game_password | string | empty | This is the one players type to join. |
require_user_verification | bool | true | When set to true, the server will only allow clients that have a valid Factorio.com account. |
max_upload_in_kilobytes_per_second | int | 0 | optional, default value is 0. 0 means unlimited. |
max_upload_slots | int | 5 | optional, default value is 5. 0 means unlimited. |
minimum_latency_in_ticks | int | 0 | optional one tick is 16ms in default speed, default value is 0. 0 means no minimum. |
max_heartbeats_per_second | int | 60 | Network tick rate. Maximum rate game updates packets are sent at before bundling them together. Minimum value is 6, maximum value is 240. |
ignore_player_limit_for_returning_players | bool | false | Players that played on this map already can join even when the max player limit was reached. |
allow_commands | string | admins-only | possible values are, true, false and admins-only |
autosave_interval | int | 10 | Autosave interval in minutes |
autosave_slots | int | 5 | server autosave slots, it is cycled through when the server autosaves. |
afk_autokick_interval | int | 0 | How many minutes until someone is kicked when doing nothing, 0 for never. |
auto_pause | bool | true | Whether should the server be paused when no players are present. |
auto_pause_when_players_connect | bool | false | Whether should the server be paused when someone is connecting to the server. |
only_admins_can_pause_the_game | bool | true | |
autosave_only_on_server | bool | true | Whether autosaves should be saved only on server or also on all connected clients. Default is true. |
non_blocking_saving | bool | false | Highly experimental feature, enable only at your own risk of losing your saves. On UNIX systems, server will fork itself to create an autosave. Autosaving on connected Windows clients will be disabled regardless of autosave_only_on_server option. |
minimum_segment_size | int | 25 | |
minimum_segment_size_peer_count | int | 20 | |
maximum_segment_size | int | 100 | |
maximum_segment_size_peer_count | int | 10 |
The one rule that saves an evening: this file proves a key is real, and it can never prove a key is fake. The settings reader ignores a key it does not recognise rather than rejecting it, so a misspelled or invented key produces no error, no log line, and no effect. A server given "port": 34567 in this file bound the default 34197 and said nothing about it; --port 34567 on the command line worked. If a setting is not in the list above, check whether it belongs on the command line before assuming the file is broken. See port configuration for the full command-line list.
Two of those defaults cause most of the "is my server broken" questions. allow_commands ships as admins-only, so a normal player's /c is refused on a fresh server that nobody has locked down. And only_admins_can_pause_the_game ships true, so players who cannot pause are looking at a default, not a decision. The live equivalents of 19 of these keys can be changed without a restart through /config set; see console commands for the mapping between the two spellings.
map-settings.json: the nine keys and what ships in them
The example map-settings.json carries nine top-level keys. Most are nested objects, and these are the shipped values that people most often want to change:
difficulty_settings:{"technology_price_multiplier": 1, "spoil_time_modifier": 1}. The first is the classic marathon knob; the second scales every spoil timer, which is the single most impactful setting for a group that finds Gleba too punishing.enemy_evolution:{"enabled": true, "time_factor": 4e-06, "destroy_factor": 0.002, "pollution_factor": 9e-07}. Those three coefficients are applied to different things, one per tick, one per destroyed spawner and one per unit of pollution, so they are not directly comparable, but the shipped spread is worth seeing:destroy_factoris 500 timestime_factorand over 2,000 timespollution_factor. Settingenabledto false freezes evolution outright.enemy_expansion: enabled by default, withmax_expansion_distance7,settler_group_min_size5,settler_group_max_size20, and a cooldown betweenmin_expansion_cooldown14400 andmax_expansion_cooldown216000 ticks, which at 60 ticks a second is 4 minutes to 1 hour.asteroids:{"spawning_rate": 1, "max_ray_portals_expanded_per_tick": 100}, the Space Age platform-danger dial.max_failed_behavior_count:3.
The remaining keys in the example are pollution, steering, unit_group and path_finder, all nested objects of tuning coefficients that are best left alone unless you are chasing a specific pathfinding problem.
map-gen-settings.json and the nine presets
The map-gen example is short, and most of it is one key. Its top-level entries are seed (null for random, or a number), width and height (both 0, meaning infinite), starting_area (1, a multiplier the file describes as the "biter free zone radius"), starting_points ([{"x": 0, "y": 0}]), peaceful_mode (false), cliff_settings, property_expression_names and autoplace_controls.
autoplace_controls is the one that matters, and the trap is that the control names are not always the resource names. On Nauvis the build defines twelve of them: coal, copper-ore, iron-ore, stone, uranium-ore, crude-oil, trees, water, rocks, enemy-base, nauvis_cliff and starting_area_moisture. Each takes frequency, size and richness, all shipped at 1. Note the mixed punctuation, hyphens on the ores and underscores on nauvis_cliff and starting_area_moisture; getting that wrong is the usual reason a hand-written map-gen file quietly generates a default world.
The build also ships nine named generation presets you can select instead of hand-writing any of this: default, rich-resources, marathon, death-world, death-world-marathon, rail-world, ribbon-world, lakes and island. The same nine exist with and without Space Age loaded, and the command line takes one by name with --preset.
If you are on a Space Age save, the other four planets define their own controls: Vulcanus has calcite, tungsten_ore, vulcanus_coal, sulfuric_acid_geyser and vulcanus_volcanism; Fulgora has scrap, fulgora_islands and fulgora_cliff; Gleba has gleba_plants, gleba_stone, gleba_water, gleba_cliff and gleba_enemy_base; and Aquilo has aquilo_crude_oil, fluorine_vent and lithium_brine.
Updating Map Rules Mid-Game
If you need to change settings that usually require a world reset (like disabling pollution or slowing down biter evolution), you must use Console Commands. Be aware that these typically disable Steam achievements.
/c game.map_settings.enemy_evolution.time_factor = 0
/c game.map_settings.pollution.enabled = false
Auto-Pause & UPS Efficiency
For large factories, we highly recommend keeping auto_pause enabled. This prevents the simulation from running while the server is empty, ensuring that biters don't evolve and your resources aren't consumed while nobody is there to defend the base.
Pro Tip: Always make a backup of your /config/ directory before editing JSON files. A single missing comma or bracket can prevent the server from starting.
Fine-tune your factory. View plans.