How to align partitions for best performance using parted

Some nicely aligned macaronsThere are two common problems when creating partitions in Linux on big storage arrays. The first is easy, and the warning message from fdisk is a bit of a giveaway:

WARNING: The size of this disk is 8.0 TB (7970004230144 bytes).
DOS partition table format can not be used on drives for volumes
larger than (2199023255040 bytes) for 512-byte sectors. Use parted(1) and GUID 
partition table format (GPT).

The answer: use parted. Don’t have it? Install it!

The second problem is this warning from parted:

(parted) mklabel gpt
(parted) mkpart primary 0 100%
Warning: The resulting partition is not properly aligned for best performance.

…and no matter what combination of numbers you use, the message just keeps coming back. It’s tempting to ignore it, but don’t.

There are a few posts on the subject, but this one from HP really gets to the guts of the problem.

Here’s a quick step-by-step guide to aligning partitions properly. It’s just an abstraction of the HP post, but hopefully easier to follow. This will work for most arrays (in fact it works for all the arrays that I’ve seen); there are more options in HP’s post, but I’ve included the most common configuration here.

  1. Get the alignment parameters for your array (remember to replace sdb with the name of your device as seen by the kernel).
    # cat /sys/block/sdb/queue/optimal_io_size
    # cat /sys/block/sdb/queue/minimum_io_size
    # cat /sys/block/sdb/alignment_offset
    # cat /sys/block/sdb/queue/physical_block_size
  2. Add optimal_io_size to alignment_offset and divide the result by physical_block_size. In my case this was (1048576 + 0) / 512 = 2048.
  3. This number is the sector at which the partition should start. Your new parted command should look like
    mkpart primary 2048s 100%

    The trailing ‘s’ is important: it tells parted that you’re talking about sectors, not bytes or megabytes.

  4. If all went well, the partition will have been created with no warnings. You can check the alignment thusly (replacing ‘1’ with the partition number if necessary):
    (parted) align-check optimal 1                                            
    1 aligned

As I alluded to before, there are cases where this won’t work: if optimal_io_size is zero, for example, there are other rules to follow. Of course it would be nice if parted could do this—the values are all available as ioctls, after all—but then what would I write about? 🙂


Filed under storage

41 Responses to How to align partitions for best performance using parted

  1. Pingback: My terrible, no-good, very bad non-guide to installing “Cubian” (Debian wheezy) on the Cubieboard 2 « Gordon Morehouse

  2. This should be forwarded to the parted mailing list a a simple and effective way of calculating if there is a more user friendly suggestion that the ones parted currently makes.

  3. Pingback: Partition alignment - performance?

  4. F2

    Very well done – thanks for doing this.

    One question: alignment offset should be in sectors according to my docs (never seen the value being other than 0) – that changes where the offset fits in your formula, does it not?

    (1048576 + 0) / 512 = 2048 should be
    1048576 / 512 + 0 = 2048
    Or did I get something wrong?

    Thanks for the excellent article! -F

  5. Roger Dahl

    Apparently, using % causes parted to automatically align the sectors for best performance:

    (parted) mkpart primary ext4 0% 100%

  6. Modeler

    Thanks for this. Agree with Roger Dahl about parted working it out for you. Here’s an awk one-liner that does the same:

    awk -v x=$(cat /sys/block/sdb/queue/optimal_io_size) -v y=$(cat /sys/block/sdb/alignment_offset) -v z=$(cat /sys/block/sdb/queue/physical_block_size) ‘BEGIN { print ( x + y ) / z }’

  7. Pingback: Deploy Ceph and start using it: end to end tutorial – Installation (part 1/3) | InIT Cloud Computing Lab

  8. steve-bc

    That is just what I was looking for. Thank you.

  9. Peter Knight

    parted has an alignment option
    -a optimal 1
    parted -s -a optimal /dev/sda mkpart primary 1 20000
    Gives the message not aligned etc but when I check
    align-check optimal 1
    I get aligned
    Why do I get the message and why does it have to be so complicatd ?

    • The optimal feature only works when you’re using inexact units. By default parted uses Megabytes which is an inexact unit but that only allows +/- 500 KB of adjustment. On my system proper alignment requires over 1MB of adjustment. So using the default of ‘Compact’ or ‘MB’ will always throw an aliment warning. Specifying a larger unit also specifies a larger adjustment range I.E. ‘GB’ allows +/- 500 MB of adjustment. The percentage unit, by it’s nature, will always have enough range to allow proper adjustment

      If you use ‘”mkpart primary 0% 20GB” that should work.

  10. Pingback: Useful post on how to align partitions with parted | Velenux Home Page

  11. Excellent tip, thank you so much.

    I put it into a little python script if anyone is interested:

    Does the same thing as Modeler’s suggestion, but you can provide the device ID as an argument and it spits out the starting sector, e.g. ` sbd`

    Thanks again!

  12. Prasad

    Gr8 document. Thanks for sharing

    Also checkout following site

  13. Nathan

    Unfortunately here are my results:
    optimal_io_size = 0
    minimum_io_size = 512
    alignment_offset = 0
    physical_block_size = 512

    So then the formula is 0 / something. Guessing this isn’t right. XenServer vm.

  14. anon

    Heh, I have the same problem as Nathan. Rackspace VM. Using “parted -a optimal” and “mkpart primary ext4 0% 100%” got me what I wanted.

  15. When I run the following command (as shown below), the result from optimal_io_size and alignment_offset are both 0 (zero) while the result from minimum_io_size and physical_block_size are both 512. This is for a new empty 128GB mSSD drive. The only thing that ended up working using the parted command was to use a starting sector of 2048s like you above. I’m confused though because my results differed so I’m still not sure why this is and why it worked – any additional insight would be much appreciated. I initially tried using a starting sector of 512s and 1024s but I still got errors with those so then I tried 2048s and only then was I able to run it without and errors.

    # cat /sys/block/sdb/queue/optimal_io_size 0 # cat /sys/block/sdb/queue/minimum_io_size 512 # cat /sys/block/sdb/alignment_offset 0 # cat /sys/block/sdb/queue/physical_block_size 512

  16. Pingback: Scripteable GPT partitions using parted | Question and Answer

  17. bill


    try this:

    parted < parted.txt

    # — parted.txt
    mktable gpt

    unit mib

    mkpart primary 1 3
    name 1 grub
    set 1 bios_grub on

    mkpart primary 3 131
    name 2 boot

    mkpart logical 131 643
    name 3 swap

    mkpart logical 643 15643
    name 4 gentoo

    mkpart logical 15643 -1
    name 5 dat


  18. Confirming that the math didn’t work out for me either.

    $ awk -v x=$(cat /sys/block/sdb/queue/optimal_io_size) -v y=$(cat /sys/block/sdb/alignment_offset) -v z=$(cat /sys/block/sdb/queue/physical_block_size) ‘BEGIN { print ( x + y ) / z }’

    However when I used percentages it worked just fine.

    $ parted /dev/sde –script — mkpart primary 0% 100%
    $ parted /dev/sde –script — print
    Model: DELL PERC H710 (scsi)
    Disk /dev/sde: 600GB
    Sector size (logical/physical): 512B/512B
    Partition Table: msdos
    Disk Flags:

    Number Start End Size Type File system Flags
    1 1049kB 600GB 600GB primary

  19. me

    parted -a opt /dev/sdb mktable gpt
    parted -a opt /dev/sdb mkpart primary 0% 100%

    worked for me.

  20. Joe

    Anyways expand gpt disk (from VMWARE) without having to reboot to the (rhel)server?
    I am able to expand msdos partition tables without having to reboot (rhel)server

  21. Pingback: 分割、格式化與掛載 Raw Disk Image « Jamyy's Weblog

  22. Pingback: Check if partitions are aligned properly for performance? | Question and Answer

  23. hi, thanks for great article.

    unfortunately on a new Seagate external USB with 5TB size it didn’t work. actually cat /sys/block/sde/queue/optimal_io_size reported 33553920 which divided by 4096 yielded 8191,875!!

    i tried many things until i simply used optimal_io_size directly:

    mkpart ext4 33553920s 98%

    and this worked!! it resulted with a start sector at 17,2GB into the disk, but with 5TB this is managable.

    • John Drake

      My 1TB HGST external drive had the same parameters. My first assumption was to round up to a nice 8192 sector partition boundary, but parted was having none of that. Calling parted with the ‘-a optimal’ parameter and specifying a mkpart partition start of 0% resulted in parted starting the first partition at sector 65535.

      Although it seems odd that this isn’t a whole number of MiB, it is the first integer value arrived at when multiplying 8191.875 by 2, 3, 4 etc. So with a little luck you may be able to move the start of your first partition left and regain some of that wasted 17 Gb.

      Personally, I don’t like having to sacrifice even 30MiB to parted’s notion of optimal alignment. Gdisk is happy to align the same drive on 8-sector boundaries, which only satisfy parted’s minimal alignment check.

  24. Daniel

    The link in the article is broken thanks to HP’s wonderful handling of their separation (into HP and HPE).

    This is probably the originally linked support article:

  25. boistordu

    I can’t apply what you said. the first line is 0 for me and it still says to me that I’m not aligned

Leave a Reply