<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>http://wiki.lustre.org/index.php?action=history&amp;feed=atom&amp;title=Lustre_Striping_Best_Practices</id>
	<title>Lustre Striping Best Practices - Revision history</title>
	<link rel="self" type="application/atom+xml" href="http://wiki.lustre.org/index.php?action=history&amp;feed=atom&amp;title=Lustre_Striping_Best_Practices"/>
	<link rel="alternate" type="text/html" href="http://wiki.lustre.org/index.php?title=Lustre_Striping_Best_Practices&amp;action=history"/>
	<updated>2026-09-02T20:00:56Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.39.7</generator>
	<entry>
		<id>http://wiki.lustre.org/index.php?title=Lustre_Striping_Best_Practices&amp;diff=5619&amp;oldid=prev</id>
		<title>Elliswilson: Created page with &quot;== Lustre Striping Best Practices ==  This page provides practical guidance for configuring Lustre file striping. It explains when and how to stripe files for different workloads, and covers features like Progressive File Layouts (PFL) and overstriping. For command reference, see Configuring Lustre File Striping.  === Striping Basics ===  Lustre can split a file&#039;s data across multiple OSTs. Each chunk is called a &#039;&#039;&#039;stripe&#039;&#039;&#039;. The two key parameters are:  * &#039;&#039;&#039;stripe...&quot;</title>
		<link rel="alternate" type="text/html" href="http://wiki.lustre.org/index.php?title=Lustre_Striping_Best_Practices&amp;diff=5619&amp;oldid=prev"/>
		<updated>2026-08-31T15:17:32Z</updated>

		<summary type="html">&lt;p&gt;Created page with &amp;quot;== Lustre Striping Best Practices ==  This page provides practical guidance for configuring Lustre file striping. It explains when and how to stripe files for different workloads, and covers features like Progressive File Layouts (PFL) and overstriping. For command reference, see &lt;a href=&quot;/Configuring_Lustre_File_Striping&quot; title=&quot;Configuring Lustre File Striping&quot;&gt;Configuring Lustre File Striping&lt;/a&gt;.  === Striping Basics ===  Lustre can split a file&amp;#039;s data across multiple OSTs. Each chunk is called a &amp;#039;&amp;#039;&amp;#039;stripe&amp;#039;&amp;#039;&amp;#039;. The two key parameters are:  * &amp;#039;&amp;#039;&amp;#039;stripe...&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;== Lustre Striping Best Practices ==&lt;br /&gt;
&lt;br /&gt;
This page provides practical guidance for configuring Lustre file&lt;br /&gt;
striping. It explains when and how to stripe files for different&lt;br /&gt;
workloads, and covers features like Progressive File Layouts (PFL)&lt;br /&gt;
and overstriping. For command reference, see&lt;br /&gt;
[[Configuring Lustre File Striping]].&lt;br /&gt;
&lt;br /&gt;
=== Striping Basics ===&lt;br /&gt;
&lt;br /&gt;
Lustre can split a file&amp;#039;s data across multiple OSTs. Each chunk is&lt;br /&gt;
called a &amp;#039;&amp;#039;&amp;#039;stripe&amp;#039;&amp;#039;&amp;#039;. The two key parameters are:&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;stripe_count&amp;#039;&amp;#039;&amp;#039; — How many OSTs to spread the file across. Default: &amp;#039;&amp;#039;&amp;#039;1&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;stripe_size&amp;#039;&amp;#039;&amp;#039; — The size of each chunk written to one OST before moving to the next. Default: &amp;#039;&amp;#039;&amp;#039;4 MiB&amp;#039;&amp;#039;&amp;#039; (compiled default in current Lustre source; some systems may override this to 1 MiB at mkfs time).&lt;br /&gt;
&lt;br /&gt;
Set with:&lt;br /&gt;
&lt;br /&gt;
 lfs setstripe -c &amp;lt;count&amp;gt; -S &amp;lt;size&amp;gt; &amp;lt;file_or_directory&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== When to Stripe (and When Not To) ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Workload !! Recommended Stripe Count !! Why&lt;br /&gt;
|-&lt;br /&gt;
| Many small files (&amp;lt; 1 MiB)&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;1&amp;#039;&amp;#039;&amp;#039; (default)&lt;br /&gt;
| Each file fits in a single stripe. Striping adds overhead:&lt;br /&gt;
  more locks, more RPCs, more OSTs involved if one fails.&lt;br /&gt;
|-&lt;br /&gt;
| Medium files (1 MiB – 1 GiB)&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;1 to 4&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| Usually one OST has enough bandwidth. Stripe wider only if&lt;br /&gt;
  multiple clients read/write the same file concurrently.&lt;br /&gt;
|-&lt;br /&gt;
| Large files (&amp;gt; 1 GiB), single client&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;4 to 8&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| Aggregates bandwidth across multiple OSTs. Diminishing returns&lt;br /&gt;
  beyond the point where network bandwidth is saturated.&lt;br /&gt;
|-&lt;br /&gt;
| Large files, many concurrent clients&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;8+&amp;#039;&amp;#039;&amp;#039; or &amp;#039;&amp;#039;&amp;#039;-1&amp;#039;&amp;#039;&amp;#039; (all OSTs)&lt;br /&gt;
| Spreads the I/O load so no single OST becomes a bottleneck.&lt;br /&gt;
  Use for shared checkpoint files or large datasets accessed&lt;br /&gt;
  in parallel.&lt;br /&gt;
|-&lt;br /&gt;
| Append-heavy workloads (logs)&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;1&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| Appends serialize at the tail — striping adds lock contention&lt;br /&gt;
  without improving throughput.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Rule of thumb:&amp;#039;&amp;#039;&amp;#039; If you don&amp;#039;t know what to use, keep the default&lt;br /&gt;
(&amp;lt;code&amp;gt;-c 1&amp;lt;/code&amp;gt;). It works well for most workloads. Only increase&lt;br /&gt;
stripe count when you have a specific performance need.&lt;br /&gt;
&lt;br /&gt;
=== Stripe Count Sizing ===&lt;br /&gt;
&lt;br /&gt;
The ideal stripe count balances I/O parallelism against overhead:&lt;br /&gt;
&lt;br /&gt;
 Ideal stripe count = required file bandwidth / per-OST bandwidth&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Example:&amp;#039;&amp;#039;&amp;#039; You need 10 GB/s for a large checkpoint file. Each&lt;br /&gt;
OST sustains 2 GB/s. Use &amp;lt;code&amp;gt;-c 5&amp;lt;/code&amp;gt; or higher.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Caution with -c -1 (all OSTs):&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Setting &amp;lt;code&amp;gt;-c -1&amp;lt;/code&amp;gt; stripes across every OST. This can cause&lt;br /&gt;
problems:&lt;br /&gt;
* When any single OST fills up, writes to the file fail with &amp;lt;code&amp;gt;ENOSPC&amp;lt;/code&amp;gt; — even if other OSTs have plenty of space. The MDS cannot skip full OSTs when the file is already allocated across all of them.&lt;br /&gt;
* Every I/O involves all OSTs, increasing the blast radius of any single OST failure.&lt;br /&gt;
&lt;br /&gt;
Use &amp;lt;code&amp;gt;-c -1&amp;lt;/code&amp;gt; only for specific large files, not as a&lt;br /&gt;
directory or filesystem default. A moderate stripe count (4–16) is&lt;br /&gt;
almost always better as a default.&lt;br /&gt;
&lt;br /&gt;
=== Stripe Size Selection ===&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Minimum:&amp;#039;&amp;#039;&amp;#039; 64 KiB (hard limit).&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Practical minimum:&amp;#039;&amp;#039;&amp;#039; 512 KiB — Lustre sends data in 1 MiB RPC chunks over the network; smaller stripe sizes waste bandwidth.&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Best for most workloads:&amp;#039;&amp;#039;&amp;#039; &amp;#039;&amp;#039;&amp;#039;1 MiB to 4 MiB&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Maximum:&amp;#039;&amp;#039;&amp;#039; 4 GiB.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Alignment tip:&amp;#039;&amp;#039;&amp;#039; Match stripe size to your application&amp;#039;s I/O&lt;br /&gt;
size when possible. If an application writes 1 MiB blocks, use a&lt;br /&gt;
1 MiB stripe size. This avoids splitting a single write across&lt;br /&gt;
two OSTs (which doubles the lock and network overhead).&lt;br /&gt;
&lt;br /&gt;
=== Progressive File Layouts (PFL) ===&lt;br /&gt;
&lt;br /&gt;
PFL (since Lustre 2.10) lets a file start with a narrow layout and&lt;br /&gt;
grow wider automatically as it gets larger. This is &amp;#039;&amp;#039;&amp;#039;the best&lt;br /&gt;
approach for mixed workloads&amp;#039;&amp;#039;&amp;#039; where you don&amp;#039;t know file sizes in&lt;br /&gt;
advance.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Example: start with 1 stripe, widen at 256 MiB, go full-width at&lt;br /&gt;
4 GiB:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
 lfs setstripe -E 256M -c 1 -S 1M \&lt;br /&gt;
               -E 4G -c 4 -S 4M \&lt;br /&gt;
               -E -1 -c -1 -S 4M \&lt;br /&gt;
               /mnt/lustre/project/&lt;br /&gt;
&lt;br /&gt;
* Files smaller than 256 MiB use 1 OST (low overhead).&lt;br /&gt;
* Files between 256 MiB and 4 GiB use 4 OSTs.&lt;br /&gt;
* Files larger than 4 GiB stripe across all OSTs.&lt;br /&gt;
&lt;br /&gt;
Set on a &amp;#039;&amp;#039;&amp;#039;directory&amp;#039;&amp;#039;&amp;#039; to apply to all new files created in it.&lt;br /&gt;
&lt;br /&gt;
PFL is strongly recommended as the default layout for directories&lt;br /&gt;
with mixed workloads. It eliminates the need to predict file sizes&lt;br /&gt;
at creation time.&lt;br /&gt;
&lt;br /&gt;
=== Overstriping ===&lt;br /&gt;
&lt;br /&gt;
Overstriping (since Lustre 2.13) allows placing &amp;#039;&amp;#039;&amp;#039;multiple stripes&lt;br /&gt;
on the same OST&amp;#039;&amp;#039;&amp;#039;. This is useful when:&lt;br /&gt;
&lt;br /&gt;
* You have more I/O threads than OSTs.&lt;br /&gt;
* You want to maximize concurrency on a small number of OSTs.&lt;br /&gt;
&lt;br /&gt;
Set with the capital &amp;lt;code&amp;gt;-C&amp;lt;/code&amp;gt; flag:&lt;br /&gt;
&lt;br /&gt;
 lfs setstripe -C 32 /mnt/lustre/workfile&lt;br /&gt;
&lt;br /&gt;
If you have 8 OSTs and request 32 stripes, each OST gets 4 stripes.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;When to use:&amp;#039;&amp;#039;&amp;#039; Overstriping primarily helps when the application&lt;br /&gt;
uses many threads and each thread operates on a different region of&lt;br /&gt;
the file. It reduces lock contention by giving each thread its own&lt;br /&gt;
stripe. It does &amp;#039;&amp;#039;&amp;#039;not&amp;#039;&amp;#039;&amp;#039; increase per-OST bandwidth.&lt;br /&gt;
&lt;br /&gt;
=== OST Pools ===&lt;br /&gt;
&lt;br /&gt;
OST pools group a subset of OSTs for targeted allocation:&lt;br /&gt;
&lt;br /&gt;
 # Create a pool&lt;br /&gt;
 lctl pool_new testfs.flash&lt;br /&gt;
&lt;br /&gt;
 # Add OSTs to the pool&lt;br /&gt;
 lctl pool_add testfs.flash OST[0-3]&lt;br /&gt;
&lt;br /&gt;
 # Stripe files to the pool&lt;br /&gt;
 lfs setstripe -p flash /mnt/lustre/fast_project/&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Use cases:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Tiered storage:&amp;#039;&amp;#039;&amp;#039; Flash pool for hot data, HDD pool for bulk.&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Rack-aware placement:&amp;#039;&amp;#039;&amp;#039; Pool per rack to keep I/O local.&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;FLR fault domains:&amp;#039;&amp;#039;&amp;#039; Use pools as mirror placement targets.&lt;br /&gt;
&lt;br /&gt;
=== Free Space Balancing ===&lt;br /&gt;
&lt;br /&gt;
Lustre automatically balances new file allocations across OSTs using&lt;br /&gt;
two algorithms:&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Round-robin:&amp;#039;&amp;#039;&amp;#039; Used when free space is roughly balanced (difference &amp;lt; 17% by default). Distributes stripes evenly across OSSs for maximum network bandwidth utilization.&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Weighted random:&amp;#039;&amp;#039;&amp;#039; Used when free space is imbalanced. Prefers OSTs with more free space.&lt;br /&gt;
&lt;br /&gt;
Key tunables:&lt;br /&gt;
&lt;br /&gt;
 # Imbalance threshold (% difference) to switch from round-robin&lt;br /&gt;
 # to weighted allocation. Default: 17&lt;br /&gt;
 lctl set_param lod.*.qos_threshold_rr=25&lt;br /&gt;
&lt;br /&gt;
 # Free-space priority weight (0-100). Default: 91&lt;br /&gt;
 # 100 = allocate purely by free space&lt;br /&gt;
 # 0 = allocate purely by location (network locality)&lt;br /&gt;
 lctl set_param lod.*.qos_prio_free=100&lt;br /&gt;
&lt;br /&gt;
=== Do Not Set the Starting OST ===&lt;br /&gt;
&lt;br /&gt;
Unless you have a specific reason, do &amp;#039;&amp;#039;&amp;#039;not&amp;#039;&amp;#039;&amp;#039; use&lt;br /&gt;
&amp;lt;code&amp;gt;lfs setstripe -i &amp;lt;ost_index&amp;gt;&amp;lt;/code&amp;gt;. Explicitly pinning files&lt;br /&gt;
to a specific starting OST causes severe imbalance — one OST fills&lt;br /&gt;
up while others remain empty.&lt;br /&gt;
&lt;br /&gt;
Let the MDS auto-select the starting OST. Its weighted algorithm&lt;br /&gt;
handles load balancing automatically.&lt;br /&gt;
&lt;br /&gt;
=== Setting Defaults ===&lt;br /&gt;
&lt;br /&gt;
Striping can be set at three levels:&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Per-file:&amp;#039;&amp;#039;&amp;#039; &amp;lt;code&amp;gt;lfs setstripe &amp;lt;file&amp;gt;&amp;lt;/code&amp;gt; — only that file.&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Per-directory:&amp;#039;&amp;#039;&amp;#039; &amp;lt;code&amp;gt;lfs setstripe &amp;lt;dir&amp;gt;&amp;lt;/code&amp;gt; — all new files created in that directory inherit the layout.&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Per-filesystem:&amp;#039;&amp;#039;&amp;#039; &amp;lt;code&amp;gt;lfs setstripe &amp;lt;mount_point&amp;gt;&amp;lt;/code&amp;gt; — default for the entire filesystem (set on the root directory).&lt;br /&gt;
&lt;br /&gt;
Directory-level defaults are the most common and practical approach.&lt;br /&gt;
&lt;br /&gt;
To view current striping:&lt;br /&gt;
&lt;br /&gt;
 lfs getstripe /mnt/lustre/myfile&lt;br /&gt;
 lfs getstripe -d /mnt/lustre/mydir   # directory default&lt;br /&gt;
&lt;br /&gt;
=== Stripe Count Limits ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Condition !! Maximum Stripe Count&lt;br /&gt;
|-&lt;br /&gt;
| ldiskfs MDT without ea_inode || 160&lt;br /&gt;
|-&lt;br /&gt;
| ldiskfs MDT with ea_inode (default since 2.13) || 2000&lt;br /&gt;
|-&lt;br /&gt;
| ZFS MDT || 2000&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
To enable wider striping on older ldiskfs MDTs:&lt;br /&gt;
&lt;br /&gt;
 tune2fs -O ea_inode /dev/mdt_device&lt;br /&gt;
&lt;br /&gt;
=== Quick Reference ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Default !! Set With&lt;br /&gt;
|-&lt;br /&gt;
| Stripe count || 1 || &amp;lt;code&amp;gt;lfs setstripe -c N&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Stripe size || 4 MiB || &amp;lt;code&amp;gt;lfs setstripe -S 4M&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Starting OST || auto-selected || &amp;lt;code&amp;gt;lfs setstripe -i N&amp;lt;/code&amp;gt; (not recommended)&lt;br /&gt;
|-&lt;br /&gt;
| Pool || none || &amp;lt;code&amp;gt;lfs setstripe -p poolname&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Overstripe count || N/A || &amp;lt;code&amp;gt;lfs setstripe -C N&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Max stripe count || 2000 || &amp;lt;code&amp;gt;lod.*.max_stripecount&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| QoS threshold || 17% || &amp;lt;code&amp;gt;lod.*.qos_threshold_rr&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Free space priority || 91% || &amp;lt;code&amp;gt;lod.*.qos_prio_free&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== See Also ===&lt;br /&gt;
&lt;br /&gt;
* [[Configuring Lustre File Striping]] — Command reference&lt;br /&gt;
* [[Progressive File Layouts]] — PFL design and advanced usage&lt;br /&gt;
* [[Creating and Managing OST Pools]] — Pool administration&lt;br /&gt;
* [[Handling Full OSTs]] — Managing OST space issues&lt;br /&gt;
* [[Lustre Common Mistakes]] — Common striping mistakes&lt;/div&gt;</summary>
		<author><name>Elliswilson</name></author>
	</entry>
</feed>