Splunk Architect Handbook

A plain-language guide to designing, setting up, and running Splunk Enterprise at scale. It covers every core component, all the common deployment shapes, the configuration files that hold everything together, and the habits that keep a large deployment healthy.

Targets Splunk Enterprise 9.x 10.x differences flagged Config files included Diagrams throughout
About versions This handbook targets the Splunk Enterprise 9.x line, with 9.4 as the reference. Splunk has since released the 10.x line as well. The core architecture is the same across both. Where 10.x changes something an architect should know, you will see a note, and the 9.x vs 10.x notes section collects the main ones. Always confirm exact numbers against the official docs for your installed build before you make a design decision.

Start here

This book is built for the person who has to make the design calls. Not just "how do I run a search," but "how many indexers do I need, how do I lose a server without losing data, and where does this setting actually belong." If you are studying for the Splunk Enterprise Certified Architect path, the topics here line up closely with what that role is expected to know.

You can read it front to back, or jump to a topic from the sidebar. Every chapter is written to stand on its own. Code blocks show real stanza names you will type into real files. Diagrams show how the pieces connect so you can picture the whole system, not just one box.

How the book is organised

What Splunk does

Splunk takes machine data and makes it useful. Machine data is the stream of text that systems write as they run: web server logs, firewall events, application traces, operating system metrics, and much more. Splunk reads that data, stores it in a way that is fast to search, and lets people ask questions of it using a search language.

The important idea for an architect is that Splunk does not need a fixed schema up front. It stores the raw data and works out the structure at the moment you search. This is often called schema on read. It is why you can point Splunk at almost any text source and start searching within minutes, and it shapes how the whole system is built.

The three things Splunk is always doing

Collect

Read data from files, network ports, scripts, APIs, and agents that sit on other machines. This is the input stage.

Store

Break the stream into events, stamp each with a time, and write them into compressed, searchable stores called indexes.

Search

Answer questions across all that stored data, build reports, alerts, and dashboards, and drive them from the Search Processing Language.

Architect takeaway Every design decision maps back to one of these three jobs. When you scale, you are really deciding how much collect, store, and search capacity you need, and how to keep each of them running when a machine fails.

The data pipeline

Before any component makes sense, you need the pipeline in your head. Every piece of data that enters Splunk moves through the same set of stages. Splunk calls this the data pipeline, and the stages are input, parsing, indexing, and search. Knowing which stage a task belongs to tells you which machine does the work and which configuration file controls it.

1. Input Read the raw stream Tag source, host, type 2. Parsing Break into events Timestamps, line merge 3. Indexing Write to buckets Build the time index 4. Search Match and extract Report and alert Forwarder / input tier Indexing tier (index-time work) Search tier (search-time work) One event, four stages Raw text enters on the left and becomes a searchable result on the right
Figure 1. The Splunk data pipeline. Work is split into index-time and search-time, which decides where each setting lives.

Stage 1: Input

At the input stage Splunk acquires the raw data as a stream of bytes. It does not yet understand where one event ends and the next begins. What it does do is attach the default metadata that will travel with the data for its whole life: the source (where it came from, such as a file path), the host (the machine that produced it), and the sourcetype (the kind of data, which tells later stages how to parse it). The file that controls this stage is inputs.conf.

Stage 2: Parsing

Parsing is where the raw stream turns into individual events. Splunk decides where each event breaks, finds the timestamp for each one, and can transform the data before it is written. This is heavy work, and it is done on an indexer or on a heavy forwarder. The main files here are props.conf and transforms.conf. Line breaking, timestamp extraction, event boundaries, and any masking of sensitive fields all happen here, at index time.

Why this matters for design Parsing is expensive. A universal forwarder does almost none of it, which is why it is light and fast. A heavy forwarder does full parsing, which is why it costs more CPU. Knowing this lets you place parsing work where you have spare capacity.

Stage 3: Indexing

At indexing, the parsed events are written to disk inside an index. Splunk writes the compressed raw data and builds the index files that make time-based search fast. Data lands in a directory called a bucket. The file that defines indexes and their storage rules is indexes.conf. Once data is indexed, it is durable and ready to search.

Stage 4: Search

Search is everything that happens when a user or a scheduled job runs a query. Field extraction that was not done at index time happens now, at search time. This is the schema on read idea in action. Most field extractions, lookups, event types, and tags are applied here, which keeps them flexible because you can change them without re-indexing. The search language that drives this stage is called the Search Processing Language, or SPL.

The index-time versus search-time rule This single distinction runs through the whole product. Work done at index time is baked into the stored data and is hard to change later. Work done at search time is applied fresh on every search and is easy to change. As an architect you push work to search time when you want flexibility, and to index time only when you must, such as for line breaking, timestamps, and data you need to mask before it is stored.
Back to top

Core components

A single Splunk Enterprise install is one piece of software. What makes it an indexer, a search head, or a forwarder is the role you give it through configuration. A small deployment might run every role on one machine. A large one spreads the roles across many machines so each can be scaled on its own. An architect needs to know every role, what it does, and how the roles talk to each other.

Data sources servers, apps, network Forwarders collect and send data Indexer tier parse, index, store answer search requests Search heads users, dashboards Management and support Cluster manager, deployer, deployment server License manager, monitoring console These configure and watch the tiers above forward search Data flows left to right, management sits underneath
Figure 2. The main tiers. Data moves from sources through forwarders to indexers, and search heads read from the indexers. A separate management group configures and watches everything.

Forwarder

A forwarder is a Splunk instance whose job is to collect data on a machine and send it somewhere else, usually to an indexer. The universal forwarder is a small, separate download built only for this. It uses little CPU and memory and is the standard agent you install on the machines you want to monitor. A heavy forwarder is a full Splunk Enterprise instance set to forward, and it can parse and route data before sending it. Forwarders are covered in depth in the Forwarders chapter.

Indexer

An indexer receives data, parses it, indexes it, and stores it on disk. It is also what searches actually run against, so it does double duty as the storage layer and the search worker. In a distributed deployment the indexers are the heart of the system. When people talk about scaling Splunk for more data, they almost always mean adding indexers. The indexer is where your disk, your ingest capacity, and much of your search speed live.

Search head

A search head is the instance people log into to run searches, build dashboards, and manage alerts. A search head does not usually store indexed data. Instead it sends the search out to the indexers, which each run their part, and then it merges the results. This split is called distributed search. In it, the search head is the coordinator and the indexers are the search peers.

Distributed search in one line The search head splits a query, the indexers each search their own slice of the data in parallel, and the search head stitches the pieces back together. More indexers means each slice is smaller, so results come back faster.

Cluster manager

The cluster manager, once called the master node, runs an indexer cluster. It does not index data itself. It keeps track of which indexers are up, decides where copies of data should live, and coordinates recovery when a node fails. It also pushes shared configuration to every indexer in the cluster so they all stay identical. There is one cluster manager per indexer cluster. It is covered in the Indexer clustering chapter.

Deployer

The deployer distributes apps and settings to the members of a search head cluster. It sits outside the cluster and cannot run on a machine that is also a cluster member. Do not confuse it with the deployment server, which manages forwarders. The deployer serves the search head cluster only. It appears again in the Search head clustering chapter.

Deployment server

The deployment server is the tool for managing configuration on many forwarders at once. You group your forwarders into server classes, map apps to those classes, and the deployment server pushes the right apps to the right machines. Without it, updating a thousand forwarders means touching a thousand machines. With it, you edit one place. See the Deployment server chapter.

License manager

The license manager, also called the license master, holds the Splunk license and tracks how much data your deployment ingests per day. Every other instance reports its daily volume to it. In a larger deployment you run one central license manager and point all other instances at it, so you have a single view of your license usage.

Monitoring Console

The Monitoring Console, sometimes still called the distributed management console, is the built-in health dashboard for the whole deployment. It shows indexing rate, search load, resource use, cluster status, and much more. In a distributed setup you dedicate one instance to run it so it can watch every other node from one place. It is your main window into whether the system is healthy.

How a single instance differs from a large deployment

RoleSingle instanceSmall distributedLarge clustered
Indexing and searchSame machineSeparate indexer and search headIndexer cluster and search head cluster
Cluster managerNot usedNot usedOne dedicated node
DeployerNot usedOptionalOne dedicated node
Deployment serverOn the single boxOften its own nodeOne or more dedicated nodes
License managerBuilt inOften centralDedicated central node
Monitoring ConsoleBuilt inOn a management nodeDedicated node
Design habit In production, keep management roles such as the cluster manager, deployer, license manager, deployment server, and Monitoring Console off the indexers and search heads that do the real data work. Management roles are light most of the time but must stay responsive during a failure, which is exactly when your data nodes are busiest.
Back to top

Deployment tiers

There are three shapes a Splunk deployment can take, and picking the right one is one of the first jobs of an architect. The shape follows the amount of data you ingest each day, how many people search, and how much downtime you can accept. You move up the ladder only when a real need pushes you there.

Single instance

One machine does everything. It reads data, indexes it, and serves searches. This is right for a proof of concept, a lab, a small team, or a department with light data. It is simple to run because there is only one box to watch. The limit is obvious: when that one machine runs out of ingest or search capacity, or when you cannot afford it going down, you have to grow.

Distributed, non-clustered

You separate the roles. One or more indexers store and search the data, and one or more search heads serve the users. Forwarders feed the indexers. This spreads the load so each tier scales on its own. You can add indexers to handle more data and add search heads to handle more users. What it does not give you on its own is automatic recovery. If an indexer dies, the data only on that indexer is unavailable until you fix it.

Forwarder tier UF host A UF host B UF host C Indexer cluster Peer 1 Peer 2 Peer 3 Peer 4 Cluster managercoordinates the peers Search head cluster SH 1 SH 2 SH 3 Deployerpushes apps to members search peers Forwarders load balance across peers. Each peer keeps copies of other peers' data so a loss is survivable.
Figure 3. A clustered distributed deployment. Forwarders feed an indexer cluster, a search head cluster serves users, and dedicated management nodes coordinate each cluster.

Clustered

This is the highly available shape. The indexers form an indexer cluster that keeps multiple copies of the data across nodes, so losing a node does not lose data or stop searches. The search heads form a search head cluster that keeps user content in sync and shares the search load. This is what you build when data cannot be lost and the service must stay up. It costs more hardware and more operational care, which is the trade you make for resilience.

QuestionSingleDistributedClustered
Daily ingestSmallGrowingLarge
Survives a node lossNoPartlyYes
Scales ingestNoAdd indexersAdd peers
Scales usersNoAdd search headsAdd cluster members
Operational effortLowMediumHigh
Grow on need, not on habit Do not cluster because clustering sounds serious. Cluster because you have a real requirement for data availability or continuous search. Every tier you add is another thing to run and another way to fail. Match the shape to the requirement.
Back to top

Splunk Validated Architectures

You do not have to invent your topology from nothing. Splunk publishes a set of tested reference designs called Splunk Validated Architectures, or SVAs. These are approved patterns for common needs, from a single server up to a multi-site cluster. Starting from an SVA means you begin with a shape Splunk has already proven, then adjust it to your case.

How to read an SVA

Each validated architecture describes the tiers involved, how many of each component you need, and what problem it solves. They are labeled with short codes. The idea is to first pick the design that matches your availability and scale needs, then size the hardware inside it. The pattern gives you the shape, and the sizing work gives you the numbers.

The pillars behind the patterns

Splunk frames good design around a few qualities: availability so the service stays up, performance so searches are fast, scalability so you can grow, security so data is protected, manageability so you can run it, and cost so it stays affordable. A validated architecture is a balance point across these. When you change a design, check what you are trading. Removing a search head cluster saves money but costs availability. Adding a site adds resilience but adds complexity.

Single site versus multi-site A single-site cluster protects you from losing a server. A multi-site cluster protects you from losing a whole data center or availability zone, because it keeps copies of data in more than one location. Multi-site is powerful but adds real complexity to replication and search. Reach for it only when a site-level failure is part of your risk model.
Back to top

Forwarders

Forwarders are how data gets into Splunk from the machines you want to watch. You install a small agent on each source machine, and it reads the logs and sends them onward. Getting this tier right matters, because it is usually the largest part of a deployment by machine count. You may have a handful of indexers and thousands of forwarders.

Universal forwarder versus heavy forwarder

Universal forwarderHeavy forwarder
What it isA small, separate, purpose-built agentA full Splunk Enterprise instance set to forward
Resource useVery low CPU and memoryFull footprint, needs real CPU
ParsingAlmost none, sends mostly rawFull parsing, can inspect events
Can filter or route by contentLimitedYes, because it parses first
Runs apps and modular inputsNo user interface, limitedYes, can run add-ons that pull from APIs
Typical useThe default agent on every hostSpecial cases: API data, heavy filtering, routing
Default to the universal forwarder Use the universal forwarder everywhere you can. It is light, easy to manage, and does not waste CPU parsing on the source machine. Reach for a heavy forwarder only when you have a real reason, such as pulling data from an app or API that needs a full instance, or doing heavy content-based filtering before data reaches the indexers.

How forwarders find indexers

A forwarder sends data to a set of receivers. The cleanest way to configure this is with an indexer discovery setup in a cluster, where the forwarder asks the cluster manager for the current list of peers. Without discovery, you list the receivers directly. The key file on the forwarder is outputs.conf, and the receiving side turns on a listener in inputs.conf.

outputs.conf on the forwarder

# Send to a group of indexers and spread the load
[tcpout]
defaultGroup = primary_indexers

[tcpout:primary_indexers]
server = idx1.example.com:9997, idx2.example.com:9997, idx3.example.com:9997

# useACK makes the forwarder wait for the indexer to confirm receipt
useACK = true

inputs.conf on the receiving indexer

# Open the receiving port so forwarders can connect
[splunktcp://9997]
disabled = 0
Load balancing A forwarder does not send everything to one indexer. It spreads data across all the receivers in its group, switching targets on a timer or at event boundaries. This is auto load balancing, and it is what keeps ingest spread evenly across your indexer tier. More indexers in the group means each one gets a smaller, fairer share.

Indexer acknowledgement

By default a forwarder considers data sent once it hands it to the network. Turn on useACK and the forwarder holds each block until the indexer confirms it was written. This protects against losing data if an indexer or the network drops at the wrong moment. It costs a little memory on the forwarder for the wait queue. For data you cannot afford to lose, turn it on.

Intermediate forwarders

Sometimes you place a forwarding tier between the source forwarders and the indexers. This is an intermediate forwarder, and it is used to cross network boundaries, to funnel traffic through a firewall gap, or to gather data from many small forwarders before sending it on. Use them when the network shape requires it, but know that every extra hop is another thing to run and can become a bottleneck if it is under-sized.

Back to top

Deployment server

Once you have more than a few forwarders, you cannot manage them by hand. The deployment server solves this. It is a Splunk instance that pushes configuration, in the form of apps, to a fleet of forwarders. You define groups of forwarders, decide which apps each group should get, and the deployment server keeps them in sync. Change one file in one place, and every matching forwarder picks it up.

The pieces

Deployment server

The instance that holds the master copies of apps and decides who gets what.

Deployment client

Any forwarder or instance that checks in and pulls its assigned apps. Configured in deploymentclient.conf.

Deployment app

A folder of configuration that gets pushed as a unit. It lives in the server's deployment-apps directory.

Server class

A rule that maps a group of clients to a set of apps. Defined in serverclass.conf.

How a client checks in

On each forwarder you point it at the deployment server with deploymentclient.conf. Giving each client a friendly name with clientName makes it much easier to target later.

# deploymentclient.conf on the forwarder
[deployment-client]
clientName = web_tier_linux

[target-broker:deploymentServer]
targetUri = deployserver.example.com:8089

Mapping clients to apps

On the deployment server, serverclass.conf defines which clients belong to which class and which apps that class receives. You match clients by hostname, IP, DNS name, or the client name you set above.

# serverclass.conf on the deployment server
[serverClass:web_tier]
whitelist.0 = web_tier_linux

[serverClass:web_tier:app:Splunk_TA_nix]
restartSplunkd = true
stateOnClient = enabled
Naming and hygiene Give deployment apps clear, consistent names so you can tell at a glance what each one does and where it should go. Use the client name to control who gets what rather than relying on fragile hostname patterns. Manage all forwarder configuration through the deployment server, and avoid editing forwarders by hand, because a later push will overwrite local changes.
One tool per job The deployment server manages forwarders and standalone instances. It does not manage indexer cluster peers or search head cluster members. Those tiers have their own tools: the cluster manager pushes to indexer peers, and the deployer pushes to search head cluster members. Mixing these up is a common and costly mistake.

Scale limits

A single deployment server can manage a large number of clients, but there is a practical ceiling that depends on how often clients check in and how big the apps are. For very large fleets you increase the check-in interval, keep apps small, or run more than one deployment server. Watch the deployment server's own load through the Monitoring Console, and confirm the current supported client count against the docs for your build before you plan a very large fleet.

Back to top

Inputs and parsing

Getting data in well is where good and bad deployments separate. Two settings decide the quality of everything downstream: the sourcetype you assign, and the parsing rules attached to it. Get these right at the start and searches are fast and clean. Get them wrong and you pay for it on every search forever.

Common input types

  • Files and directories. Splunk tails log files and picks up new lines as they are written. The most common input by far.
  • Network inputs. Splunk listens on a TCP or UDP port for data such as syslog. TCP is preferred over UDP because UDP can silently drop data under load.
  • Scripted inputs. A script runs on a schedule and its output becomes data. Useful for pulling from a command or a small API.
  • Modular inputs and HTTP Event Collector. Structured ways for apps and code to send data. HTTP Event Collector, or HEC, lets applications send events straight to Splunk over HTTP with a token, with no forwarder needed.
Syslog and UDP Sending syslog straight into a Splunk UDP port works but risks dropping data and ties the load to one machine. The common production pattern is to land syslog on a dedicated syslog server, write it to files, and have a universal forwarder read those files. This gives you a buffer on disk and load balancing across your indexers.

The big eight parsing settings

Most parsing problems come down to a small set of settings in props.conf, applied per sourcetype. Setting these explicitly, rather than letting Splunk guess, makes ingest faster and more reliable.

SettingWhat it controls
SHOULD_LINEMERGEWhether Splunk tries to merge multiple lines into one event. Set to false when one line is one event.
LINE_BREAKERThe pattern that marks where a new event starts. The most reliable way to break events correctly.
TIME_PREFIXThe text that comes right before the timestamp, so Splunk looks in the right place.
TIME_FORMATThe exact format of the timestamp, so Splunk reads it correctly.
MAX_TIMESTAMP_LOOKAHEADHow far into the event Splunk scans for the timestamp. Keep it tight for speed.
TZThe time zone of the data, so events land at the correct absolute time.
TRUNCATEThe maximum event length before Splunk cuts it off. Raise it for long events.
EVENT_BREAKERUsed with the universal forwarder to help split events correctly before sending.

A clean sourcetype definition

# props.conf, applied on the indexer or heavy forwarder
[my_app_log]
SHOULD_LINEMERGE = false
LINE_BREAKER = ([\r\n]+)\d{4}-\d{2}-\d{2}
TIME_PREFIX = ^
TIME_FORMAT = %Y-%m-%d %H:%M:%S
MAX_TIMESTAMP_LOOKAHEAD = 25
TZ = UTC
TRUNCATE = 10000
Where parsing settings live Index-time parsing settings must be present where parsing happens. That means on the indexers, or on a heavy forwarder if you parse there. Putting these settings only on a universal forwarder does not work, because the universal forwarder does not do full parsing. This is one of the most common setup mistakes.
Back to top

Indexer clustering

An indexer cluster is a group of indexers that keep copies of each other's data. If one indexer fails, the copies on the others keep the data available and searchable. This is how Splunk delivers data availability. Understanding the cluster is the single most important skill for an architect, because it is where your data safety and much of your capacity planning live.

The roles

  • Cluster manager. One per cluster. It coordinates the peers, tracks the copies, and drives recovery. It does not index data.
  • Peer nodes. The indexers themselves. They receive data, index it, keep copies of other peers' data, and run searches.
  • Search heads. They get their list of peers from the cluster manager and search across all of them.

Replication factor and search factor

Two numbers define how safe your data is. The replication factor is how many total copies of each bucket of data the cluster keeps. The search factor is how many of those copies are searchable, meaning they include the index files needed to search, not just the raw data.

Replication factor 3, search factor 2 Three total copies of each bucket, two of them ready to search Peer 1 Bucket A (searchable) Bucket B (copy) Peer 2 Bucket B (searchable) Bucket A (searchable) Peer 3 Bucket A (copy) Bucket B (copy) Green is a searchable copy. Blue is a raw copy that can be made searchable if a peer is lost.
Figure 4. Replication factor 3 keeps three copies of each bucket spread across peers. Search factor 2 keeps two of them ready to search. If any single peer dies, at least one searchable copy still exists.

The common default is a replication factor of 3 and a search factor of 2. That means each bucket exists on three peers, and two of those copies are fully searchable. With this setup the cluster can lose one peer and keep all data available and searchable. The trade is disk: a replication factor of 3 means you store roughly three times the raw indexed volume, and the searchable copies add more on top.

The rule of thumb A cluster can tolerate the loss of replication factor minus 1 peers without losing data. So a replication factor of 3 survives losing 2 peers. The search factor must be less than or equal to the replication factor, because a copy cannot be searchable if it does not exist. Higher numbers mean more safety and more disk.

The bucket lifecycle

Data does not sit still. Each bucket moves through stages as it ages, from hot where new data is written, to warm, to cold, and finally to frozen where it leaves the searchable system. This lifecycle is how Splunk balances fast recent data against cheap old storage. It is covered in detail in the Indexes and buckets chapter, and it applies inside a cluster just as it does on a single indexer.

Setting up the manager

# server.conf on the cluster manager
[clustering]
mode = manager
replication_factor = 3
search_factor = 2
pass4SymmKey = yourClusterSecret
cluster_label = prod_cluster

server.conf on each peer

[clustering]
mode = peer
manager_uri = https://cm.example.com:8089
pass4SymmKey = yourClusterSecret
[replication_port://9887]
Managing peer configuration In a cluster you do not edit each peer by hand. You place shared configuration in the cluster manager's manager-apps area and use the apply bundle action to push it to every peer at once. This keeps all peers identical, which the cluster requires. Files pushed this way land in the peer-app location and take the highest precedence on the peer.

Multi-site clusters

A multi-site cluster spreads peers across two or more locations and lets you say how many copies must live at each site. This protects you from losing a whole site, not just a single server. It uses site-aware replication and search so that, where possible, a search reads from local copies to save bandwidth. Multi-site adds real complexity, so use it only when a site failure is a risk you must plan for.

Back to top

Search head clustering

A search head cluster is a group of search heads that share the same user content and spread the search workload. If one member fails, users keep working on the others, and their dashboards, saved searches, and reports are all still there. This is how Splunk delivers availability for the search tier.

The captain

One member of the cluster acts as the captain. The captain is not a separate machine. It is a role that one of the members takes on. The captain coordinates the cluster: it schedules the shared jobs, replicates changes to knowledge objects across all members, and keeps everyone in sync. The role is dynamic, meaning any member can become captain, and the cluster elects a new one automatically if the current captain fails.

Search head cluster Deployer pushes apps to all members Captain member acting as leader Member 2 Member 3 knowledge objects replicated across members The deployer sits outside the cluster. The captain is one of the members, chosen by election.
Figure 5. A search head cluster. Members replicate user content among themselves, one acts as captain, and a separate deployer pushes apps to all of them.

The deployer

The deployer is a separate instance that pushes apps and base configuration to all the cluster members. It must not be a member itself, and it must not run on a cluster member. You use it to roll out an app or a settings change to every member in one action. Day-to-day user content, such as a dashboard someone saves, is handled by replication among the members, not by the deployer. The deployer is for the shared base; replication is for live user changes.

Deployer versus deployment server, again The deployer serves a search head cluster. The deployment server serves forwarders. They sound alike and are easy to confuse, but they are different tools for different tiers. Keep them straight in your head and in your diagrams.

Why you need an odd number of members

The captain is chosen by a majority vote. For a vote to have a clear majority, you want an odd number of members. With an odd count the cluster can always form a majority on one side of a network split, which prevents two halves from both electing a captain. The common minimum for a real search head cluster is three members. Fewer than three cannot safely handle the loss of a member and still hold a majority.

Connecting it to the indexers

To search clustered indexers, you configure each search head cluster member as a search head on the indexer cluster. Then the members get their peer list from the cluster manager automatically. Splunk recommends that the secret key for the search head cluster be different from the secret key for the indexer cluster, so the two clusters stay cleanly separated.

Keep indexed data off the search heads Store indexed data on the indexer tier only. Search heads should not hold the bulk indexed data. This keeps the search tier light, avoids the need for expensive fast storage on every search head, and makes the whole design simpler to reason about.
Back to top

Indexes and buckets

An index is where Splunk stores data on disk. Inside an index, data is held in directories called buckets, and each bucket holds events from a span of time. Understanding buckets is how you understand storage cost, search speed, and retention. It is one of the most practical skills for an architect, because it turns "keep 90 days of data" into real disk numbers.

What is in a bucket

A bucket holds two main things: the compressed raw data as it arrived, and the index files that make searching fast. The raw data compresses well, often to a small fraction of its original size. The index files add some overhead on top. The combined size on disk is what you plan capacity around, not the raw log size alone.

The bucket lifecycle

Buckets age through a fixed set of stages. New data is written to hot buckets. When a hot bucket fills up or reaches an age limit, it rolls to warm, meaning it is closed but still on fast storage. Later it rolls to cold, which can be on cheaper, slower storage. Finally it rolls to frozen, at which point Splunk either deletes it or hands it to you to archive. There is also a thawed state for data you bring back from an archive.

A bucket ages from hot to frozen HOT being written fast storage WARM closed, searchable fast storage COLD searchable cheaper storage FROZEN deleted or archived not searchable THAWED restored from archive Buckets roll forward as they fill or age. Frozen is the end of the searchable life. Thawing is a manual restore.
Figure 6. The bucket lifecycle. Hot and warm sit on fast storage, cold can sit on cheaper storage, and frozen leaves the searchable system.

Controlling retention and storage

You control all of this in indexes.conf. The two levers that matter most are time and size. Data freezes when it is older than frozenTimePeriodInSecs, or when the index grows past maxTotalDataSizeMB, whichever comes first. You point hot and warm at fast storage with homePath, cold at cheaper storage with coldPath, and set where frozen data goes.

# indexes.conf
[web_prod]
homePath   = /fast/splunk/web_prod/db
coldPath   = /bulk/splunk/web_prod/colddb
thawedPath = /bulk/splunk/web_prod/thaweddb

# keep data for 90 days
frozenTimePeriodInSecs = 7776000

# cap the index at 500 GB
maxTotalDataSizeMB = 500000

# run this script when a bucket freezes, instead of deleting it
coldToFrozenScript = /opt/splunk/bin/archive_bucket.sh
Frozen means gone by default When a bucket freezes, Splunk deletes it unless you tell it otherwise. If you must keep data past its searchable life, set coldToFrozenDir or a coldToFrozenScript to archive it first. Many teams have lost data by not setting this. Decide your retention and archive policy before data starts flowing, not after.

Index design tips

  • Separate indexes by data type and access needs. Put data with different retention, sensitivity, or access rules in different indexes. Access control is granted per index, so this is how you keep the right eyes on the right data.
  • Do not make hundreds of tiny indexes. Every index carries some overhead. Group sensibly rather than creating one per source.
  • Plan retention up front. Retention drives disk, and disk drives cost. Know how long each index must hold data before you size anything.
  • In a cluster, indexes.conf must match on every peer. Push it from the cluster manager so all peers agree.
Back to top

SmartStore

SmartStore changes where the bulk of your data lives. Instead of keeping all warm and cold data on local disk on each indexer, SmartStore keeps the master copy in remote object storage, such as Amazon S3 or a compatible on-premises store, and uses local disk only as a cache for the data being actively searched. This lets you scale storage and compute separately, which is a major shift in how you size a deployment.

SmartStore: cache local, keep the master copy remote Indexer 1 local cache Indexer 2 local cache Indexer 3 local cache Remote object store S3, GCS, Azure Blob, or S3-compatible on-premises. Holds the master copy of warm data. fetch on search, evict when idle Data missing from the cache is pulled from the object store on demand, then dropped when no longer needed.
Figure 7. SmartStore. Indexers keep a working cache on local disk and fetch anything else from the remote store when a search needs it.

Why it matters for design

Without SmartStore, if you need to keep more data, you add indexers just to get more local disk, even if you do not need more compute. With SmartStore, you grow cheap object storage for capacity and add indexers only when you need more compute or ingest. This decoupling is the whole point.

Sizing the local cache

The local disk becomes a cache, not the full store. It must be large enough to hold the working set, meaning the data your searches actually touch. Splunk guidance is to size the cache to hold roughly the equivalent of the most recent period your searches commonly cover, often described as around 30 days of data, though the right number depends on your search patterns. If searches often reach older data, that data has to be fetched from the remote store, which is slower.

Practical requirements Use fast local storage such as SSD or NVMe for the cache. Use strong network connectivity between the indexers and the object store, with 10 Gbps recommended for good performance. The object store type ties you to where indexers run: S3 pairs with running in AWS, GCS with GCP, Azure Blob with Azure, and S3-compatible on-premises storage with an on-premises data center. Confirm exact version and storage support against the docs for your build.
SmartStore in one sentence SmartStore turns local disk into a cache and moves the real storage to a cheap, scalable object store, so you stop buying indexers just to buy disk.
Back to top

Configuration files

Almost everything in Splunk is controlled by plain text files that end in .conf. The web interface is a friendly front end, but underneath it writes to these same files. An architect works with the files directly, because that is where the real control and the real troubleshooting happen. Learn the file system and you can configure and fix anything.

How the files are organised

Configuration lives inside apps. An app is just a folder under $SPLUNK_HOME/etc/apps. Inside each app, settings can live in three places, and the place decides the priority:

  • default. The default folder holds settings that ship with the app. You never edit these, because an upgrade can overwrite them.
  • local. The local folder holds your changes. This is where you put your settings, and it wins over default.
  • System. The etc/system/local folder holds deployment-wide settings that sit above the apps.
The golden rule of editing Put your changes in local, never in default. Default is the vendor's copy and gets replaced on upgrade. Local is yours and survives. This one habit prevents a whole class of "my settings vanished after the upgrade" problems.

The structure of a .conf file

Every conf file has the same shape. Square brackets define a stanza, which is a named block. Under each stanza are settings written as key = value. Comments start with a hash.

# a stanza header in square brackets
[my_sourcetype]
# key = value pairs under it
SHOULD_LINEMERGE = false
TItle = example
Back to top

Precedence and btool

When the same setting appears in more than one place, Splunk has to decide which one wins. That decision is called configuration file precedence, and it is one of the most important things an architect must truly understand. Most "why is this setting not working" problems are really precedence problems: your setting exists, but another copy with higher priority is overriding it.

The order that decides the winner

For most files, when Splunk merges settings it takes the highest priority copy first, then fills in anything missing from lower priority copies. The general order, from highest to lowest, is system local, then app local, then app default, then system default. In short, your system-wide overrides beat app overrides, and any local beats any default.

Precedence, highest wins etc/system/local deployment-wide overrides you set app / local your changes inside an app app / default settings the app shipped with etc/system/default Splunk built-in defaults, never edit HIGH LOW This is the general order. Index-time and cluster peer configs use an expanded order.
Figure 8. Configuration precedence. A setting higher in the stack overrides the same setting lower down.
Two important exceptions First, when the file is being used globally, such as at index time, the merge treats system local as the top and default as the bottom, which is the order shown above. When settings apply per user or per app in the search context, the order shifts to favor the user's own app. Second, in an indexer cluster there is an expanded order, and configuration pushed from the cluster manager to the peer-app location takes the highest precedence on the peer. When in doubt, do not guess. Use btool.

btool, the settings you actually get

Because precedence is layered, the setting you wrote is not always the setting that wins. The btool command shows you the final merged result, taking precedence into account. It is your ground truth for "what will Splunk actually use." It reports what would apply on the next restart, in order of precedence.

# show the merged props.conf as Splunk will use it
$SPLUNK_HOME/bin/splunk btool props list --debug

# check one sourcetype and see which file each setting came from
$SPLUNK_HOME/bin/splunk btool props list my_sourcetype --debug

# check inputs, outputs, indexes the same way
$SPLUNK_HOME/bin/splunk btool inputs list --debug
The debug flag is the magic Adding --debug makes btool print the exact file each winning setting came from. When a setting is not behaving, run btool with debug, find which file is winning, and you have found your problem in seconds instead of hunting through folders by hand.
Back to top

Key .conf reference

There are many conf files, but a working architect touches a core set constantly. Here is what each one does and where it belongs. Knowing the right file for a job is half the battle.

FileWhat it controlsWhere it usually lives
inputs.confWhat data to collect and receiving portsForwarders and indexers
outputs.confWhere a forwarder sends dataForwarders and heavy forwarders
props.confParsing rules and field extraction per sourcetypeIndexers, heavy forwarders, search heads
transforms.confTransforms used by props, such as masking and routingWith props.conf
indexes.confIndex definitions, paths, and retentionIndexers, pushed by the cluster manager
server.confInstance roles, clustering, general settingsEvery instance
web.confThe web interface, ports, and SSL for the UISearch heads and any instance with a UI
authentication.confHow users log in, such as LDAP or SAMLSearch heads
authorize.confRoles and what each role can doSearch heads
deploymentclient.confPoints a forwarder at its deployment serverDeployment clients
serverclass.confMaps clients to deployment appsDeployment server
limits.confSearch limits and resource capsSearch heads and indexers

Which tier needs which file

A frequent mistake is putting a setting on the wrong tier. Parsing settings in props.conf need to be where parsing happens, which is the indexers or heavy forwarders. Search-time field extractions in props.conf need to be on the search heads. Receiving ports in inputs.conf belong on the indexers. Sending settings in outputs.conf belong on the forwarders. When a setting does not seem to work, first ask whether it is even on the right machine.

Index-time versus search-time, in the files Some settings in props.conf act at index time, such as line breaking and timestamps, and must live on the parsing tier. Others act at search time, such as most field extractions, and must live on the search tier. The same file serves both, so the tier you place it on is what decides whether it works.
Back to top

Sizing and capacity

Sizing is the work of turning a requirement into a number of machines. It is where an architect earns their keep. Under-size and the system is slow and fragile. Over-size and you waste money. The good news is that sizing follows a clear method: start from ingest and search load, apply the reference hardware, and add up.

Reference hardware

Splunk publishes reference hardware specifications so you have a known-good baseline for a single indexer or search head. For the 9.4 line, Splunk describes tiers of specification. The mid-range specification is built around 24 physical CPU cores, or 48 vCPU at 2 GHz or greater per core, along with generous memory and fast storage. There is a smaller entry specification and a high-performance specification above it.

Specification tier (9.4 reference)CPU
Entry12 physical cores, or 24 vCPU at 2 GHz or more per core
Mid-range24 physical cores, or 48 vCPU at 2 GHz or more per core
High-performance48 physical cores, or 96 vCPU at 2 GHz or more per core
Confirm the numbers for your build Reference hardware changes between releases, and memory and storage figures matter as much as CPU. Treat the numbers here as the shape of the guidance, and confirm the exact CPU, memory, IOPS, and storage values against the reference hardware page for your installed version before you commit to a purchase. I am giving you the method and the current shape, not a guarantee of every figure for every build.

The storage side

Indexer storage must be fast. Splunk expresses this in IOPS, the number of input and output operations per second the disks can sustain. As a scale example from Splunk's own guidance, a shared storage array serving ten indexers at solid-state performance would need on the order of 40,000 concurrent IOPS, which is roughly 4,000 IOPS per indexer. Slow storage starves searches no matter how much CPU you have, so this is not a place to cut corners.

How many indexers

The main driver of indexer count is daily ingest volume, balanced against search load. Each indexer can handle a certain amount of data ingest per day at the reference specification, and searching adds to that load. You divide your total daily volume by the per-indexer ingest capacity, then add indexers for search concurrency, for headroom, and for the replication overhead if you cluster.

A worked way of thinking

  1. Find your daily ingest in gigabytes per day, and be honest about peaks, not just averages.
  2. Divide by the ingest each indexer can handle at your chosen specification to get a base indexer count.
  3. Add indexers for search load, since heavy searching reduces how much each indexer can ingest.
  4. If clustering, remember replication multiplies the disk you need and adds some CPU.
  5. Add headroom so you are not running at the edge, and so you can lose a node without pain.
Do not size from averages alone A deployment sized to the daily average will fall over at the daily peak. Size for peak ingest and peak concurrent searches. It is common to find the busy hour carries several times the average rate. Ask for real numbers before you decide, and do not invent them.

Search head sizing

Search heads are driven by how many people search, how many scheduled searches run, and how heavy those searches are. The reference hardware applies here too. In a search head cluster you add members for both availability and to spread scheduled search load, keeping an odd number so captain election stays clean.

The two dials Indexers scale with data volume and search load. Search heads scale with user and scheduled search count. Keep the two concerns separate in your head, size each on its own driver, and you will avoid both the under-built and the over-built extremes.
Back to top

Security

A Splunk deployment holds a lot of sensitive data, and it is often part of the security team's own tooling, so it has to be locked down well. Security in Splunk falls into a few clear areas: who can log in, what they can do once in, and how data is protected as it moves and rests.

Authentication

Authentication is how users prove who they are. Splunk supports local accounts, but in any real deployment you tie it to your existing identity system, usually LDAP or Active Directory, or single sign-on through SAML. This is set in authentication.conf. Central identity means you manage joiners and leavers in one place, and you get your organisation's password and multi-factor rules for free.

Authorization with roles

Authorization is what a user is allowed to do. Splunk uses role-based access control. You assign users to roles, and each role carries a set of capabilities and a set of indexes it can search. This is defined in authorize.conf. Because index access is granted per role, splitting sensitive data into its own index is how you keep it visible only to the right roles.

Built-in roleRough meaning
adminFull control of the instance
powerCan create shared content and real-time searches, but not administer
userBasic search and personal content

You rarely rely on the built-in roles alone. You build custom roles that match your teams, grant each only the indexes and capabilities it needs, and inherit from the built-ins where it helps. Least privilege is the goal: give each role the smallest set of powers that lets it do its job.

Protecting data in motion and at rest

  • Encrypt traffic. Turn on TLS for forwarder-to-indexer traffic, for the management port, and for the web interface. This protects data as it crosses the network.
  • Mask sensitive data at index time. If data contains secrets you must not store, use props.conf and transforms.conf to mask or drop it before it is written. Once it is indexed, it is much harder to remove.
  • Protect the secret keys. The cluster secret keys, set with pass4SymmKey, guard membership in your clusters. Keep them safe and use different keys for the indexer cluster and the search head cluster.
  • Control the management port. The management port, usually 8089, is powerful. Restrict who can reach it at the network level.
Separate data with indexes Access control is granted per index, so your index design is also a security design. Put data with different sensitivity or different audiences in different indexes from the start. Retrofitting this later, after everything landed in one index, is painful.
Back to top

Monitoring and troubleshooting

A large Splunk deployment needs to be watched like any other critical system. The good news is that Splunk is very good at watching itself, because it indexes its own logs. Your main tools are the Monitoring Console, Splunk's internal logs, and a handful of commands.

The Monitoring Console

The Monitoring Console is the built-in health center for the whole deployment. It shows indexing rate, search activity, resource use per instance, cluster health, and much more. In a distributed setup you set up one instance as the console and register every other node with it, so you get a single pane of glass across the environment. Check it regularly, and set up its health alerts so problems find you instead of the other way around.

Splunk's own logs

Splunk writes its internal logs into an index called _internal. Because it is just another index, you can search it with SPL like any data. This is where you go when something is wrong. The most useful file is splunkd.log, which records what the core process is doing, including errors and warnings.

# find recent errors across the deployment
index=_internal source=*splunkd.log log_level=ERROR

# watch indexing throughput per indexer
index=_internal source=*metrics.log group=per_index_thruput

Common problems and where to look

SymptomFirst place to look
A setting is not taking effectRun btool with --debug to see which file wins
Data is not arrivingCheck forwarder outputs.conf, the receiving port on the indexer, and splunkd.log on both
Events break in the wrong place or have wrong timesCheck the parsing settings in props.conf on the parsing tier
Searches are slowCheck indexer CPU, storage IOPS, and search concurrency in the Monitoring Console
Cluster shows missing copiesCheck the cluster manager status and peer health
A search head cluster is unstableCheck member count, captain status, and network between members

Useful command line tools

# overall health of an indexer cluster, run on the cluster manager
splunk show cluster-status

# search head cluster status, run on a member
splunk show shcluster-status

# validate configuration files before a restart
splunk btool check
Watch the trend, not just the moment A single busy moment is normal. What tells you about real health is the trend over days and weeks: is ingest growing, is search load climbing, is free disk shrinking. Use the Monitoring Console to watch trends so you add capacity before you run out, not after.
Back to top

Operations Book

This chapter is the hands-on companion to the rest of the handbook. It is the page you keep open while you work. It gathers the directories and configuration files you touch most, the commands to run and manage Splunk day to day, the commands to add data and monitors, and clear guidance on which machine each command belongs on. Everything here is meant to be copied and used.

Two things to know first Splunk installs into a home directory called $SPLUNK_HOME. On Linux the default is /opt/splunk for a full instance and /opt/splunkforwarder for a universal forwarder. On Windows it is usually C:\Program Files\Splunk. The command line tool lives in $SPLUNK_HOME/bin. Almost every command in this chapter is run from there, either as ./splunk on Linux or splunk on Windows.

Directories and conf files

This is the master table. It lists the important directories first, then the configuration files grouped by what they do. Every path is relative to $SPLUNK_HOME unless stated. Use it to answer two questions fast: where does this thing live, and which file controls this behavior.

Important directories

PathWhat it holds
bin/The splunk command line tool and helper binaries. You run commands from here.
etc/The root of all configuration. Everything below is under here.
etc/system/default/Splunk's built-in default settings. Never edit these.
etc/system/local/Your deployment-wide overrides. Highest general precedence.
etc/apps/All installed apps and add-ons. Most configuration lives inside apps here.
etc/apps/<app>/default/Settings an app shipped with. Do not edit.
etc/apps/<app>/local/Your changes to that app. This is where you edit.
etc/users/Per-user private configuration and content.
etc/deployment-apps/On a deployment server, the apps it pushes to forwarders.
etc/manager-apps/On a cluster manager, the apps it pushes to indexer peers. Older builds name this master-apps.
etc/shcluster/On a deployer, the apps and base config it pushes to search head cluster members.
etc/slave-apps or etc/peer-appsOn an indexer peer, the config received from the cluster manager. Highest precedence on the peer.
var/lib/splunk/The default location where indexed data and buckets are stored.
var/log/splunk/Splunk's own log files, including splunkd.log. Also searchable in the _internal index.
var/run/splunk/Runtime state and dispatch directories for running searches.

Configuration files by purpose

These are the files you place inside an app's local folder, or in etc/system/local. The tier column tells you which machine the file usually belongs on.

Getting data in

FileWhat it controlsUsual tier
inputs.confWhat data to collect and the receiving ports for forwarded dataForwarders and indexers
outputs.confWhere a forwarder sends its dataForwarders and heavy forwarders
props.confParsing rules and field extraction per sourcetypeIndexers, heavy forwarders, search heads
transforms.confNamed transforms used by props, such as masking and routingWith props.conf
wmi.confWindows management instrumentation inputsWindows forwarders
inputs.conf (HEC stanza)HTTP Event Collector tokens and settingsIndexers or heavy forwarders

Storage and indexing

FileWhat it controlsUsual tier
indexes.confIndex definitions, storage paths, retention, and SmartStoreIndexers, pushed by the cluster manager
segmenters.confHow events are split into searchable segmentsIndexers
datamodels.confData model definitions and accelerationSearch heads

Instance, roles, and clustering

FileWhat it controlsUsual tier
server.confInstance identity, roles, clustering mode, general settingsEvery instance
web.confThe web interface, ports, and its SSLSearch heads and any UI instance
deploymentclient.confPoints a forwarder at its deployment serverDeployment clients
serverclass.confMaps clients to deployment appsDeployment server
distsearch.confDistributed search and search peer settingsSearch heads
alert_actions.confWhat alerts do when they fire, such as emailSearch heads

Security and access

FileWhat it controlsUsual tier
authentication.confHow users log in, such as LDAP or SAMLSearch heads
authorize.confRoles, capabilities, and index accessSearch heads
passwdLocal user credentials, hashed. Not a conf file but sits in etc/Each instance
user-seed.confSets the first admin account on initial startAny instance, first boot
limits.confSearch limits and resource capsSearch heads and indexers

Search-time knowledge

FileWhat it controlsUsual tier
savedsearches.confSaved searches, reports, and alertsSearch heads
macros.confSearch macrosSearch heads
tags.confTags applied to field valuesSearch heads
eventtypes.confEvent type definitionsSearch heads
fields.confField settings, such as indexed fields and multivalueSearch heads and indexers
transforms.confLookups and field transforms used at search timeSearch heads
collections.confKV store collectionsSearch heads
The one habit that matters here Whatever the file, your copy goes in a local folder, and the vendor copy stays in default. When two copies of a setting disagree, run splunk btool <file> list --debug to see which one wins and where it came from.
Back to top

Start, stop, and manage

These are the commands that run the Splunk process itself. On Linux, change into $SPLUNK_HOME/bin and run them as ./splunk, or use the full path /opt/splunk/bin/splunk. On Windows, run splunk from the same bin folder in a command prompt, or use the Services panel. Many commands need administrator or root rights, so you may need sudo on Linux.

Service control

# from $SPLUNK_HOME/bin
./splunk start                 # start Splunk
./splunk stop                  # stop Splunk
./splunk restart               # stop then start
./splunk status                # is it running
./splunk version               # show the version

# accept the license without the prompt, useful in scripts
./splunk start --accept-license

# restart only one part instead of the whole instance
./splunk restart splunkd       # the core engine
./splunk restart splunkweb     # the web interface

Start at boot

# make Splunk start automatically when the machine boots
sudo ./splunk enable boot-start

# run it as a systemd service (modern Linux), managed by systemd
sudo ./splunk enable boot-start -systemd-managed 1 -user splunk

# turn boot start off
sudo ./splunk disable boot-start
Systemd note When Splunk is set up as a systemd service, the ./splunk start, stop, and restart commands are mapped to the matching systemctl commands under the hood. You can also run systemctl start Splunkd directly. Use one approach consistently so you do not fight the service manager.

Config, users, and indexes

# check that config files are valid before a restart
./splunk btool check

# see the final merged settings for a file, with source files
./splunk btool inputs list --debug

# change the admin password
./splunk edit user admin -password 'NewStrongPass' -auth admin:oldpass

# add and list indexes
./splunk add index security_logs
./splunk list index

# reload the deployment server after editing serverclass.conf
./splunk reload deploy-server

# log in once so later commands do not ask for credentials
./splunk login -auth admin:yourpassword

Cluster and search head cluster

# run on the cluster manager: push shared config to all indexer peers
./splunk apply cluster-bundle

# run on the cluster manager: overall indexer cluster health
./splunk show cluster-status

# run on a search head cluster member: cluster status
./splunk show shcluster-status

# run on a search head: add a standalone indexer as a search peer
./splunk add search-server https://idx1.example.com:8089 -auth admin:pass -remoteUsername admin -remotePassword pass
Restarts are not free Restarting an indexer or a cluster peer interrupts indexing and searches on that node. In a cluster, restart peers one at a time and let the cluster recover between each, or use the rolling restart action from the cluster manager. Never restart every peer at once in production.
Back to top

Add data and monitors

This is how you tell Splunk to start reading a source from the command line, without editing files by hand. The general pattern is ./splunk [add|edit|remove|list] [monitor|oneshot|tcp|udp] source -parameter value. These commands write to inputs.conf for you. Run them on the machine that will read the data, which is usually a forwarder.

Monitor files and directories

# watch a single log file, picking up new lines as they arrive
./splunk add monitor /var/log/messages

# watch a whole directory and everything under it
./splunk add monitor /var/log/nginx/

# set the index and sourcetype at the same time
./splunk add monitor /var/log/app/app.log -index app_logs -sourcetype my_app_log

# override the host value for this input
./splunk add monitor /var/log/dmesg -hostname web01 -index os_logs

# list, edit, and remove monitors
./splunk list monitor
./splunk edit monitor /var/log/app/app.log -index new_index
./splunk remove monitor /var/log/app/app.log

Index a file one time

# read a file once, right now, and do not keep watching it
./splunk add oneshot /var/log/old/archive.log -index import_index -sourcetype my_app_log
Monitor versus oneshot Use add monitor for a live source that keeps growing, such as an active log file. Use add oneshot to pull in a fixed file a single time, such as loading an old log for a one-off investigation. Oneshot does not keep watching the file after it finishes.

Network inputs

# listen for data on a TCP port, for example raw syslog
./splunk add tcp 514 -sourcetype syslog -index network

# listen on a UDP port (prefer TCP where you can, UDP can drop data)
./splunk add udp 514 -sourcetype syslog -index network

Forwarding and receiving

# on a forwarder: send data to an indexer
./splunk add forward-server idx1.example.com:9997

# on the receiving indexer: turn on the listener for forwarded data
./splunk enable listen 9997

# list and remove forward destinations
./splunk list forward-server
./splunk remove forward-server idx1.example.com:9997
These commands edit conf files for you Everything here ends up in inputs.conf or outputs.conf in the app you are working in, usually the search app's local folder or the app named on the command. That means you can either run the command or edit the file by hand, and the result is the same. After a change, a restart or an input reload makes it take effect.
Back to top

Where to run commands

The most common cause of a command not working as expected is running it on the wrong machine. Splunk commands act on the local instance, so you must run each one on the instance that owns that job. This table maps the common commands to where they belong.

CommandRun it onWhy
start, stop, restart, statusAny instance, locallyIt controls that machine's own Splunk process only.
add monitor, add oneshotThe instance that reads the data, usually a forwarderThe input must exist where the file or source lives.
add tcp, add udp, enable listenThe instance that receives the data, usually an indexerThe listening port opens on the receiver.
add forward-serverThe forwarder that sends dataIt sets where that forwarder sends to.
add index, list indexAn indexer, or the cluster manager for a clusterIndexes live on the indexing tier. In a cluster, define them once on the manager and push.
apply cluster-bundle, show cluster-statusThe cluster managerOnly the manager coordinates the indexer cluster.
show shcluster-statusA search head cluster memberMembers hold the cluster state.
reload deploy-serverThe deployment serverIt manages the forwarder fleet configuration.
apply shcluster-bundleThe deployerThe deployer pushes apps to search head cluster members.
edit user, authorize changesThe search head (or the relevant instance)Authentication and roles are managed where users log in.
Authentication on commands Many management commands need credentials. Add -auth username:password to the command, or run ./splunk login once first so the session is remembered. In scripts, prefer a dedicated service account over the main admin account, and avoid putting plain passwords in files that others can read.
In one line Run service commands anywhere locally, run input commands where the data is read or received, and run cluster commands on the manager, deployer, or member that owns that cluster. Match the command to the role and most problems disappear.
Back to top

Q&A: how-to guides

This is the practical part of the book. Each guide below takes one real task an architect gets asked to do and walks through it step by step, with the exact files, commands, and the machine each step runs on. Read the ones you need, or work through them all. For quick recall practice, use the separate Quick-fire Q&A page, and to test yourself, use the Exercises page.

Conventions used below Commands are shown in the Linux form, run from $SPLUNK_HOME/bin as ./splunk. On Windows, drop the ./. Where a step must run on a specific machine, the guide says so in bold. Replace example hostnames, ports, and passwords with your own. Confirm version-specific flags against the docs for your build.

1. Filter and route events using a Splunk forwarder

Goal: drop the events you do not want, and send the rest to different indexers or indexes based on their content. Because this needs the data to be parsed first, it must run on a heavy forwarder or on the indexers, not on a universal forwarder. A universal forwarder does not parse, so it cannot filter by content.

Step 1. Understand the two jobs

Filtering means sending unwanted events to a special destination called nullQueue, which throws them away. Routing means tagging events with a target group so they go to a chosen set of receivers. Both are done with a pair of files: props.conf assigns a transform to a sourcetype, and transforms.conf defines what that transform does.

Step 2. Filter: drop events you do not want

Say you want to keep everything except the noisy DEBUG lines from a sourcetype called app_log. On the heavy forwarder or indexer, in an app's local folder:

# transforms.conf
# first, a catch-all could route everything, then this sends DEBUG to the void
[drop_debug]
REGEX = \bDEBUG\b
DEST_KEY = queue
FORMAT = nullQueue
# props.conf
[app_log]
TRANSFORMS-drop = drop_debug
Keep some, drop the rest pattern A common trick is to first route everything to nullQueue, then route the events you want to keep back to the normal indexing queue. You do this by listing two transforms in order: one that sets the queue to null for all events, and one with a tighter regex that sets the queue back to indexQueue for the keepers. Order matters, because the last matching transform wins.
# transforms.conf, keep only lines containing ERROR or WARN
[set_null]
REGEX = .
DEST_KEY = queue
FORMAT = nullQueue

[keep_important]
REGEX = (ERROR|WARN)
DEST_KEY = queue
FORMAT = indexQueue
# props.conf, apply both in order
[app_log]
TRANSFORMS-filter = set_null, keep_important

Step 3. Route: send events to a specific indexer group

Define the target groups in outputs.conf, then use a transform to stamp matching events with the group name via the special key _TCP_ROUTING. On the heavy forwarder:

# outputs.conf, two named groups
[tcpout]
defaultGroup = primary

[tcpout:primary]
server = idxA:9997, idxB:9997

[tcpout:security_idx]
server = sec-idx1:9997, sec-idx2:9997
# transforms.conf, send firewall events to the security group
[route_firewall]
REGEX = firewall
DEST_KEY = _TCP_ROUTING
FORMAT = security_idx
# props.conf
[app_log]
TRANSFORMS-route = route_firewall

Step 4. Apply and confirm

./splunk btool props list app_log --debug   # confirm the transforms are attached
./splunk restart                            # or reload as appropriate
Why not on a universal forwarder Filtering and content routing read inside the event, which only happens after parsing. Universal forwarders forward raw data without parsing, so these rules have nothing to act on there. Put the rules where parsing happens: a heavy forwarder or the indexers.

2. Monitor Windows logs using a universal forwarder

Goal: collect Windows Event Logs, such as Security and System, from a Windows host and send them to your indexers. This runs on the Windows universal forwarder installed on that host.

Step 1. Install the universal forwarder on Windows

Install the Windows universal forwarder package on the host. During install you can point it at your deployment server and your receiving indexers, or set those later. The forwarder runs as a Windows service called SplunkForwarder.

Step 2. Define the Windows inputs

Windows Event Logs use a special input stanza. On the forwarder, in %SPLUNK_HOME%\etc\apps\your_app\local\inputs.conf:

# inputs.conf on the Windows universal forwarder
[WinEventLog://Security]
disabled = 0
index = win_security

[WinEventLog://System]
disabled = 0
index = win_os

[WinEventLog://Application]
disabled = 0
index = win_os
Use the Splunk Add-on for Windows Rather than hand-writing these, the common practice is to deploy the official Splunk Add-on for Microsoft Windows, which ships tested inputs and field extractions. You push it to your Windows forwarders through the deployment server and enable the inputs you need.

Step 3. Point the forwarder at your indexers

# outputs.conf on the forwarder
[tcpout]
defaultGroup = indexers

[tcpout:indexers]
server = idx1:9997, idx2:9997

Or set it from the command line on the forwarder:

splunk add forward-server idx1:9997 -auth admin:password

Step 4. Make sure the index exists and restart

On the indexers (or the cluster manager for a cluster), create the target indexes so the data has a home, then restart the forwarder.

# on an indexer
splunk add index win_security
splunk add index win_os

# on the Windows forwarder
splunk restart

Step 5. Confirm data is arriving

On a search head, run a search over a recent window: index=win_security. If nothing shows, check the receiving port is enabled on the indexer, and read splunkd.log on the forwarder for connection errors.

3. How does Splunk scale?

Goal: understand the levers you pull to make Splunk handle more data and more users. The short answer is that Splunk scales out, not up. You add more machines to each tier rather than buying one giant server.

Scaling ingest and storage

Ingest and storage live on the indexers. To handle more data per day, you add more indexers and spread the incoming data across them. Forwarders load balance automatically across all the indexers you give them, so each new indexer takes a share of the load. More indexers also means each search touches a smaller slice of data, so searches stay fast as data grows.

Scaling search and users

Search and users live on the search heads. To handle more people and more scheduled searches, you add search heads. When you need availability as well, you group them into a search head cluster so user content stays in sync and the load spreads across members.

Scaling availability

To survive a machine failing, you cluster. An indexer cluster keeps multiple copies of data across peers so losing a peer loses no data. A search head cluster keeps user content on every member so losing a member loses no work. A multi-site cluster spreads copies across locations to survive a whole site failing.

Scaling storage separately from compute

With SmartStore you keep the bulk of data in cheap remote object storage and use local disk only as a cache. This lets you grow storage without adding indexers just for disk, so you scale storage and compute on their own schedules.

Scale each tier by adding machines to it More data in add indexers forwarders load balance or use SmartStore for storage More users add search heads cluster them for availability Survive failure indexer cluster keeps copies multi-site for site loss Each tier scales on its own driver, so you grow only the part that is under pressure.
Figure 9. Splunk scales horizontally. Data pressure adds indexers, user pressure adds search heads, and availability needs drive clustering.

4. Distributed search setup and configuration

Goal: let one search head search across several separate indexers. This is the simplest distributed setup, without clustering. You configure the search peers on the search head.

Step 1. Prepare the indexers as search peers

Each indexer that will be searched is a search peer. It just needs to be running and reachable on its management port, usually 8089, from the search head.

Step 2. Add each peer on the search head

On the search head, add every indexer as a search peer. Run this once per peer:

./splunk add search-server https://idx1.example.com:8089 \
    -auth admin:shpassword \
    -remoteUsername admin -remotePassword idxpassword

./splunk add search-server https://idx2.example.com:8089 \
    -auth admin:shpassword \
    -remoteUsername admin -remotePassword idxpassword

This writes to distsearch.conf and exchanges keys so the search head can query each peer.

Step 3. Confirm the peers

./splunk list search-server

Or check Settings, then Distributed search, then Search peers in the web interface. Peers should show as Up.

Step 4. Search

Run any search on the search head. It now fans out to all peers and merges the results. No special syntax is needed. If a peer shows down, check the management port is reachable and the credentials are correct.

Do not mix with a clustered setup this way If your indexers are an indexer cluster, you do not add them one by one. Instead you connect the search head to the cluster manager, and it hands the search head the peer list automatically. Manual search peers are for standalone, non-clustered indexers. See guide 5 and the clustering chapters.

5. Configure the deployer and set up a search head cluster

Goal: build a working search head cluster of three members, with a deployer that pushes apps to them. This touches four machines: the deployer and three members. A search head cluster needs at least three members for safe captain election.

Step 1. Set up the deployer

The deployer is a standalone Splunk instance that is not a member. On the deployer, edit server.conf to set a shared secret and a cluster label. The pass4SymmKey here must match the one you give the members.

# server.conf on the deployer
[shclustering]
pass4SymmKey = yourShcSecret
shcluster_label = prod_shc

Restart the deployer after this change.

Step 2. Initialise each member

On each of the three members, run the init command. Use the same secret and point each member at the deployer. Do not run this on the deployer.

./splunk init shcluster-config \
    -auth admin:password \
    -mgmt_uri https://sh1.example.com:8089 \
    -replication_port 9200 \
    -replication_factor 3 \
    -conf_deploy_fetch_url https://deployer.example.com:8089 \
    -secret yourShcSecret \
    -shcluster_label prod_shc

./splunk restart

Change -mgmt_uri to each member's own address as you run it on that member. The replication factor here is how many copies of user content the cluster keeps across members.

Step 3. Bootstrap the captain

Run the bootstrap command on one member only. List all members in the servers list. This starts the cluster and elects the first captain.

./splunk bootstrap shcluster-captain \
    -servers_list "https://sh1.example.com:8089,https://sh2.example.com:8089,https://sh3.example.com:8089" \
    -auth admin:password

Step 4. Confirm the cluster is healthy

./splunk show shcluster-status -auth admin:password

You should see all three members and one captain.

Step 5. Push apps from the deployer

Place apps in the deployer's $SPLUNK_HOME/etc/shcluster/apps folder, then push them to all members with one command on the deployer:

./splunk apply shcluster-bundle -target https://sh1.example.com:8089 -auth admin:password
Two roles, do not mix The deployer pushes the shared app base. Live user changes, such as a saved dashboard, replicate among members automatically. Never put the deployer inside the cluster, and never use the forwarder deployment server for this job.

6. Add or remove members from a search head cluster

Goal: grow or shrink an existing cluster safely. These commands run on the member being added, or on any current member for a removal.

Add a member

First initialise the new instance with the same settings as the others, using init shcluster-config as in guide 5, then restart it. Then join it to the cluster. You can run the add command on the new member, pointing at a current member:

# on the NEW member, point at any existing member
./splunk add shcluster-member \
    -current_member_uri https://sh1.example.com:8089 \
    -auth admin:password

Or run it from a current member, pointing at the new one:

# on a CURRENT member, point at the new member
./splunk add shcluster-member \
    -new_member_uri https://sh4.example.com:8089 \
    -auth admin:password
Adding overwrites the new member Joining an instance to a search head cluster replaces its existing apps and configuration with the cluster's. Do not add a search head that has content you need unless you have moved that content into the deployer first. Keep the member count odd where you can, so captain election stays clean.

Remove a member

Run the remove command on any cluster member. For a member that is still running, target it by its URI:

./splunk remove shcluster-member -mgmt_uri https://sh4.example.com:8089 -auth admin:password

If you plan to keep that instance for another use, disable its cluster config after removing it, and do not stop it before you remove it. For a member that has already failed and is down, run the same command from a healthy member to clean it out of the cluster.

7. Configure a static captain in a search head cluster

Goal: pin the captain role to one specific member instead of letting the cluster elect one. You do this in a special situation: when the cluster has lost so many members that it cannot form a majority to elect a dynamic captain, such as during a site outage. A static captain lets the survivors keep working. These commands run on every remaining member.

Static captain is a recovery tool, not a normal mode In normal running you want a dynamic captain, because it re-elects automatically when the captain fails. Use a static captain only to keep a crippled cluster searchable during an outage, and switch back to dynamic once the cluster is whole again. A static captain does not fail over on its own.

Step 1. Pick the member to be captain

Choose one healthy member. On that member, set it to be the static captain and turn off election:

./splunk edit shcluster-config -election false -mode captain \
    -captain_uri https://sh1.example.com:8089 -auth admin:password

Step 2. Point every other member at that captain

On each remaining member, turn off election and name the same captain:

./splunk edit shcluster-config -election false -mode member \
    -captain_uri https://sh1.example.com:8089 -auth admin:password

Step 3. Confirm

./splunk show shcluster-status -auth admin:password

The chosen member should now hold the captain role, and election should be off.

Step 4. Return to a dynamic captain when recovered

Once enough members are back to form a majority, turn election back on so the cluster manages the captain itself again. On every member:

./splunk edit shcluster-config -election true -mgmt_uri https://shX.example.com:8089 -auth admin:password
./splunk restart
Verify the exact flags for your build The static captain flags have stayed stable across recent releases, but small differences exist between versions. Before you run this during a real outage, confirm the exact edit shcluster-config options against the documentation for your installed version, and practice the steps in a lab first.

8. Set up an indexer cluster (bonus)

Goal: build a basic single-site indexer cluster with one manager and several peers. Runs on the cluster manager and each peer.

On the cluster manager

# server.conf on the manager
[clustering]
mode = manager
replication_factor = 3
search_factor = 2
pass4SymmKey = yourClusterSecret
cluster_label = prod_idx

On each peer

# server.conf on each peer
[clustering]
mode = peer
manager_uri = https://cm.example.com:8089
pass4SymmKey = yourClusterSecret
[replication_port://9887]

Restart the manager first, then each peer. On a search head, connect to the cluster so it learns the peer list:

# server.conf on the search head
[clustering]
mode = searchhead
manager_uri = https://cm.example.com:8089
pass4SymmKey = yourClusterSecret

Push shared config to all peers from the manager with ./splunk apply cluster-bundle, and check health with ./splunk show cluster-status.

9. Mask sensitive data before indexing (bonus)

Goal: hide secrets, such as card numbers, so they are never stored. This is index-time work, so it runs on the indexers or a heavy forwarder. The simplest tool is SEDCMD in props.conf.

# props.conf, replace all but the last 4 digits of a 16 digit number
[app_log]
SEDCMD-mask_card = s/\d{12}(\d{4})/xxxxxxxxxxxx\1/g
Once indexed, it is hard to remove Masking must happen before the data is written. If sensitive data is already indexed, masking rules will not clean it. Get this right before the source goes live.

10. Manage forwarders with a deployment server (bonus)

Goal: push an app to many forwarders from one place. Runs on the deployment server and each forwarder.

On each forwarder

# deploymentclient.conf
[deployment-client]
clientName = linux_web

[target-broker:deploymentServer]
targetUri = ds.example.com:8089

Or set it from the command line: ./splunk set deploy-poll ds.example.com:8089, then restart.

On the deployment server

Put the app in $SPLUNK_HOME/etc/deployment-apps/, define who gets it in serverclass.conf, then reload:

[serverClass:web]
whitelist.0 = linux_web
[serverClass:web:app:Splunk_TA_nix]
restartSplunkd = true
stateOnClient = enabled
./splunk reload deploy-server
Back to top

Best practices

These are the habits that separate a deployment that runs quietly for years from one that fights you every week. None of them are complicated. They are about discipline and doing the boring things consistently.

Configuration

  • Put every change in local, never in default, so upgrades do not wipe your work.
  • Package related settings into named apps rather than scattering them. Apps are easy to move, version, and reason about.
  • Use btool whenever a setting does not behave. Do not guess about precedence.
  • Manage forwarders through the deployment server, cluster peers through the cluster manager, and search head members through the deployer. One tool per tier.

Getting data in

  • Default to the universal forwarder. Use heavy forwarders only for a real reason such as API inputs or heavy filtering.
  • Set the sourcetype and parsing settings explicitly. Do not rely on Splunk guessing line breaks and timestamps.
  • Put index-time parsing settings on the parsing tier, meaning indexers or heavy forwarders, not on universal forwarders.
  • Turn on indexer acknowledgement for data you cannot afford to lose.
  • Land syslog on a dedicated collector and read the files with a forwarder, rather than pointing syslog straight at a Splunk UDP port.

Storage and indexes

  • Decide retention and archive policy before data flows, and set the freeze behavior so you do not silently delete data.
  • Separate data into indexes by retention, sensitivity, and audience, because access is granted per index.
  • Keep hot and warm on fast storage. Cold can be cheaper. Consider SmartStore when storage growth outpaces compute need.
  • In a cluster, keep indexes.conf identical across peers by pushing it from the cluster manager.

Availability

  • Cluster only when you have a real availability requirement, not by default.
  • Keep an odd number of search head cluster members so captain election always has a majority.
  • Keep management roles off the data nodes so they stay responsive during a failure.
  • Use different secret keys for the indexer cluster and the search head cluster.

Operations

  • Register every node with the Monitoring Console and watch trends, not just moments.
  • Size for peak load, not the daily average.
  • Test upgrades and configuration changes somewhere safe before production.
  • Document your topology, your index design, and your retention rules so the next person can follow them.
Back to top

Architect checklist

Use this as a fast pass over a design, whether you are building new or reviewing something you inherited. If you cannot answer a line clearly, that is where to dig.

Requirements

  • What is the daily ingest volume, at peak, not just average?
  • How long must each type of data be retained, and what happens after?
  • How many people search, and how many scheduled searches run?
  • What downtime and data loss can the business actually accept?

Topology

  • Does the deployment shape, single, distributed, or clustered, match the availability requirement?
  • Is there a validated architecture this maps to?
  • Is it single site or multi-site, and does that match the site-failure risk?

Data in

  • Are forwarders universal by default, with heavy forwarders only where justified?
  • Is there a deployment server plan for managing the forwarder fleet?
  • Are sourcetypes and parsing settings defined explicitly and placed on the right tier?

Storage

  • Is index design set by retention, sensitivity, and audience?
  • Are replication factor and search factor chosen and understood?
  • Is the freeze and archive behavior set so nothing is lost by accident?
  • Is SmartStore considered where storage growth outpaces compute?

Sizing

  • Is indexer count derived from peak ingest plus search load plus headroom?
  • Does storage meet the IOPS the workload needs?
  • Is search head count set by user and scheduled search load, with an odd cluster size?

Security and operations

  • Is authentication tied to central identity, with least-privilege roles?
  • Is traffic encrypted and are secret keys protected and separated?
  • Is every node registered with the Monitoring Console?
  • Is the whole design documented for the next person?
Back to top

9.x versus 10.x notes

This handbook targets Splunk Enterprise 9.x, with 9.4 as the reference. Splunk has since shipped the 10.x line, and the current release as of mid 2026 is in the 10.x series, with 9.4.x continuing as a maintained line. The core architecture in this book, the pipeline, the components, clustering, buckets, and the configuration system, is the same across both lines. That is why the concepts here carry forward.

What an architect should do Design with the concepts in this book, then confirm the specific numbers and any feature changes against the documentation for the exact build you will run. Reference hardware, supported storage options, and default values can shift between releases. The method does not change, but the figures can, so always check the version-specific page before you commit a design decision. Where I am not certain a value still holds for your build, treat it as something to verify, not a fact to trust blindly.

What tends to stay the same

  • The four-stage data pipeline and the index-time versus search-time split.
  • The component roles: indexers, search heads, forwarders, cluster manager, deployer, deployment server, license manager, Monitoring Console.
  • Replication factor and search factor as the core of indexer cluster resilience.
  • The captain and deployer model for search head clusters.
  • The bucket lifecycle and the configuration file and precedence system.

What tends to move between releases

  • Exact reference hardware figures for CPU, memory, IOPS, and storage.
  • Supported object storage options and specifics for SmartStore.
  • Default values inside conf files, and newly added settings.
  • Platform and operating system support, and end-of-life dates for older lines.
Naming note Some role names changed over time. The old master node is now the cluster manager, and the old license master is now the license manager. You will still see the older names in older docs, community posts, and some command output. They mean the same roles described here.
Back to top

Glossary

TermPlain meaning
BucketA directory holding events from a span of time, plus the index files to search them.
CaptainThe member of a search head cluster that coordinates the others. Chosen by election.
Cluster managerThe node that runs an indexer cluster. Formerly the master node.
DeployerThe instance that pushes apps to search head cluster members.
Deployment serverThe instance that manages configuration on forwarders.
Distributed searchA search head splitting a query across many indexers and merging the results.
ForwarderAn instance that collects data and sends it to indexers.
Heavy forwarderA full Splunk instance set to forward, able to parse and route data.
IndexA named store of data on disk, made of buckets.
Index timeWork done as data is stored. Hard to change later.
IndexerAn instance that parses, indexes, stores, and searches data.
Knowledge objectUser-created content such as a saved search, field extraction, lookup, or dashboard.
License managerThe node that holds the license and tracks daily volume. Formerly the license master.
Monitoring ConsoleThe built-in health dashboard for the whole deployment.
Peer nodeAn indexer that is a member of an indexer cluster.
Replication factorHow many total copies of each bucket the cluster keeps.
Search factorHow many of those copies are ready to search.
Search headThe instance people use to run searches and build dashboards.
Search timeWork done when a search runs. Easy to change.
Server classA rule mapping a group of forwarders to a set of deployment apps.
SmartStoreA storage model that keeps the master copy of data in remote object storage and caches locally.
SourcetypeThe label that tells Splunk what kind of data an event is and how to parse it.
SPLSearch Processing Language, the language used to search Splunk.
Universal forwarderThe small, light agent that collects and forwards data with little parsing.
Sources and verification The version, architecture, sizing, and configuration details in this handbook were checked against Splunk's official documentation and release information current to mid 2026. Numbers such as reference hardware figures and supported storage options can change between releases, so confirm anything you will build on against the docs for your exact installed version.
Back to top