Blog
How to Dock Multiple Ligands in AutoDock Vina (Batch Docking): A Step-by-Step Guide
- August 14, 2026
- Posted by: Stemskills Lab
- Category: Molecular Modeling

Batch docking runs the same receptor, the same grid box and the same scoring function against many ligand files in one command, sequentially, writing one output PDBQT per ligand. AutoDock Vina 1.2 does this with the --batch flag and --dir for the output directory. A shell loop is the fallback for older builds and for multiple receptors.
You already know how to dock one ligand in AutoDock Vina. Then week two of the project arrives, your supervisor hands you 40 compounds instead of one, and you find yourself running Vina by hand once per file and copying affinities out of the terminal into a spreadsheet by eye. That step is where docking projects lose a weekend and pick up errors nobody can trace later. This guide covers it end to end, written by the StemSkills Lab team from 10+ years in structural bioinformatics, drug design and multiscale molecular modeling.
What is batch docking, and how is it different from multiple ligand docking?
These are two different features of AutoDock Vina with confusingly similar names, they have separate documentation pages, and students conflate them constantly. Getting this wrong does not produce an error message. It produces a result that looks fine and means nothing.
- Batch mode docks each ligand separately and sequentially against the receptor. One ligand in the pocket at a time, one output file each. This is what a screening-style project wants.
- Multiple ligand docking places several ligands in the site at the same time. The official documentation describes it as a fragment-based design technique, where “small molecules that bind the same target can be grown or combined into larger compounds with potentially better affinity.”
The Docking in batch mode page carries the warning in plain words: “Do not confuse this with multiple ligand docking, in which multiple ligands are docked simultaneously.” If you reach for --ligand lig1.pdbqt lig2.pdbqt lig3.pdbqt expecting a ranked list of three compounds, you will instead get one score for all three sitting in the pocket together, and no way to rank anything.
The tell is the flag. Multiple ligands after --ligand means simultaneous. Repeated --batch arguments mean sequential.
What has to stay identical across every ligand in the run?
Three things, and this is the rule that makes your final table rankable: one receptor PDBQT, one config file, one grid box.
Vina scores are relative. A number like -8.4 kcal/mol carries no absolute meaning on its own, so the only thing you can honestly do with a set of them is order them. That ordering is valid only when every compound was scored under identical conditions. A student who re-centres the box for each ligand, or who resizes it because one compound looked cramped, has produced a column of numbers that cannot be compared with each other. The table looks the same. It is no longer a ranking.
Batch mode enforces this for you, which is a quiet second reason to prefer it over a hand-run loop: one --config file applies to the entire run. Set the box once, on the pocket, using the grid box centre and size procedure, and size it for the largest compound in your set rather than the first one you happened to open. A config file is three centre coordinates and three dimensions:
center_x = 15.190
center_y = 53.903
center_z = 16.917
size_x = 20.0
size_y = 20.0
size_z = 20.0Those values come from the basic docking tutorial for the imatinib/c-Abl system. Yours will differ. What must not differ is that every ligand in the run sees the same six numbers.
How do you prepare 40 ligands to PDBQT without clicking through a GUI 40 times?
This is the question the official documentation does not answer, because it starts from a folder of prepared PDBQT files. Getting to that folder is the actual work. There are three sub-steps, and each has a failure mode.
Step 1: split the multi-molecule file
Compound sets arrive from PubChem or ChEMBL as one SDF holding all the molecules. Passing that file to Vina as a single ligand docks 40 molecules as one absurd super-ligand. Split it first. Open Babel’s -m option exists precisely for this, described in the Open Babel command line documentation as putting “each molecule into consecutively numbered output files”:
obabel ligands.sdf -O lig.sdf -mThat writes lig1.sdf, lig2.sdf and so on. The numbering follows the order of the records in the source file, which gives you a mapping back to compound identity if you capture the titles in the same order:
obabel ligands.sdf -osmi -O ligands_index.smiKeep that index file. Six weeks later, when a reviewer asks which compound lig27 was, it is the only thing standing between you and re-running the set.
Step 2: generate 3D coordinates if the source is 2D
A large share of database downloads are flat. Docking a 2D structure produces poses that are geometric nonsense, and Vina will not warn you. Open Babel’s --gen3d option handles this, and the same command can set a protonation state appropriate to physiological pH:
for f in lig*.sdf; do
obabel "$f" -O "${f%.sdf}_3d.sdf" --gen3d -p 7.4
doneOpen Babel is the general-purpose converter here, and the Open Babel paper (O’Boyle, Banck, James, Morley, Vandermeersch and Hutchison, Journal of Cheminformatics 2011;3:33) reports that version 2.3 “interconverts over 110 formats”. Our file format conversion guide covers the syntax in more depth.
Step 3: convert the folder to PDBQT
Two routes, and the choice matters more than most tutorials admit. Open Babel writes PDBQT directly in a loop:
for f in lig*_3d.sdf; do
obabel "$f" -O "${f%_3d.sdf}.pdbqt"
doneThe AutoDock Vina 1.2 documentation instead uses Meeko, which is the route the developers recommend and which handles torsion trees and atom typing the way Vina expects:
mk_prepare_ligand.py -i lig1_3d.sdf -o lig1.pdbqtWrap that in the same for loop over your files. Use Meeko when you can install it, Open Babel when you cannot. The same documentation carries a warning worth repeating: it advises “against using PDB format for preparing small molecules, since it does not contain information about bond connections.” Start from SDF or MOL2, never PDB. Our guide on how to prepare the protein and ligand for docking covers the receptor half, which you do exactly once for the whole batch.
What is the exact command to run batch docking in AutoDock Vina?
The usage is identical to a single-ligand run with one substitution: --batch replaces --ligand, and it can be given once or many times. From the official documentation:
vina --receptor 1iep_receptor.pdbqt \
--batch ligands/1iep_ligand_1.pdbqt \
--batch ligands/1iep_ligand_2.pdbqt \
--batch ligands/1iep_ligand_3.pdbqt \
--config config.txt --dir posesFor a whole folder, a shell wildcard expands to the same thing:
vina --receptor 1iep_receptor.pdbqt --batch ligands/*.pdbqt --config config.txt --dir posesOn Windows PowerShell the wildcard needs help, and the documentation gives the form --batch $(ls .\ligands\*.pdbqt | % {$_.FullName}).
Two behaviours to know before you run it. First, output naming: the docs state that “the output filename will be <ligand_name>_out.pdbqt under the specified directory, where <ligand_name> is the name of the input ligand file without the path.” Second, collisions: “when the name of the ligand is duplicated, an index will be added to the name to avoid the name collision.” That index is silent, so duplicated input names are how a results table quietly stops mapping back to compounds.
Each ligand prints its own progress bar and its own mode table to the log, in the same format as a single run:
mode | affinity | dist from best mode
| (kcal/mol) | rmsd l.b.| rmsd u.b.
-----+------------+----------+----------
1 -14.72 0 0
2 -14.63 0.862 1.051
3 -13.12 1.152 1.877Mode 1 is always the best-scoring pose for that ligand. That is the number your ranking uses.
Want the guided, hands-on version?
Our live Molecular Modeling & MD Simulations cohort bootcamp takes you from zero to running real docking and MD workflows, with a portfolio project for your grad-school applications.
When do you need a shell loop instead of –batch?
Two situations. The first is an older Vina build without the flag, where a plain loop over ligands does the same job:
for lig in ligands/*.pdbqt; do
name=$(basename "$lig" .pdbqt)
vina --receptor receptor.pdbqt --ligand "$lig" \
--config config.txt --out "poses/${name}_out.pdbqt"
doneThe second is more than one receptor, and here the documentation is explicit: “Currently, there is no option to iterate multiple receptors in a series of docking runs.” You script it yourself. The docs give the pattern, which nests batch mode inside a receptor loop and keeps each receptor’s results in its own directory:
#!/bin/bash
for receptor in receptors/*.pdbqt; do
receptor_name=$(basename "$receptor" .pdbqt)
vina --receptor "$receptor" --batch ligands/*.pdbqt \
--config config.txt --dir "poses/$receptor_name"
doneOne caution on that script: a single shared config.txt only works when every receptor is superimposed in the same coordinate frame. Different crystal structures usually are not, so each receptor generally needs its own box file.
How do you turn 40 output files into one ranked table?
Every student reinvents this badly, usually by opening files one at a time. Vina writes the score into each output PDBQT as a REMARK VINA RESULT line, one per mode, in the order they appear in the log table. The first such line in the file is the best pose, and the first number on it is the predicted affinity in kcal/mol, followed by the two RMSD bounds.
So the whole extraction is one loop:
for f in poses/*_out.pdbqt; do
name=$(basename "$f" _out.pdbqt)
best=$(awk '/^REMARK VINA RESULT/{print $4; exit}' "$f")
printf "%s\t%s\n" "$name" "$best"
done | sort -k2 -n > results.tsvThe exit in the awk block is what restricts you to the top mode, and sort -k2 -n puts the most negative affinity first. If you prefer Python:
import csv, glob, os
rows = []
for path in sorted(glob.glob("poses/*_out.pdbqt")):
with open(path) as fh:
for line in fh:
if line.startswith("REMARK VINA RESULT"):
name = os.path.basename(path).replace("_out.pdbqt", "")
rows.append((name, float(line.split()[3])))
break
rows.sort(key=lambda r: r[1])
with open("results.csv", "w", newline="") as out:
writer = csv.writer(out)
writer.writerow(["ligand", "best_affinity_kcal_mol"])
writer.writerows(rows)What lands in your thesis is a two-column table, sorted ascending, with the compound name resolved from your index file rather than left as lig27:
| Ligand | Best affinity (kcal/mol) |
|---|---|
| Compound A | -9.8 |
| Compound B | -9.1 |
| Compound C | -8.4 |
| Reference ligand | -8.2 |
Those numbers are placeholders for layout. Include your co-crystallised or known-active compound as a row in the same run: without that internal reference, a column of affinities has nothing to be judged against. The guide to interpreting docking results covers what the values do and do not support.
Which method should you use to dock a ligand set?
Four realistic options, and the right answer depends on how much command line you are willing to write.
| Method | How you run it | Command line needed | Ligand prep | Output organisation | Results table for you | Multiple receptors | Best for |
|---|---|---|---|---|---|---|---|
Vina --batch | One command, ligands passed as arguments | Yes | You prepare PDBQT yourself | All poses into --dir, one file per ligand | No, you extract it | No, wrap in a loop | The default for a prepared ligand folder |
Shell for loop | Script over ligand files | Yes | You prepare PDBQT yourself | Whatever your --out pattern says | No, you extract it | Yes, nest a second loop | Older Vina builds, several receptors |
| PyRx | Graphical interface, import and select | No | Converts and minimises in the interface | Managed internally | Yes, sortable in the interface | One at a time | Beginners, small sets, no terminal |
| Vina Python bindings | from vina import Vina in a script | Yes, plus Python | Your script’s job | Whatever your script writes | Yes, if you write it | Yes, in code | Custom logic, reproducible pipelines |
The Python route uses the API introduced with version 1.2.0, documented by Eberhardt, Santos-Martins, Tillack and Forli in AutoDock Vina 1.2.0: New Docking Methods, Expanded Force Field, and Python Bindings (Journal of Chemical Information and Modeling 2021;61(8):3891-3898). A minimal run looks like this:
from vina import Vina
v = Vina(sf_name='vina')
v.set_receptor('1iep_receptor.pdbqt')
v.set_ligand_from_file('1iep_ligand.pdbqt')
v.compute_vina_maps(center=[15.190, 53.903, 16.917], box_size=[20, 20, 20])
v.dock(exhaustiveness=32, n_poses=20)
v.write_poses('1iep_ligand_vina_out.pdbqt', n_poses=5, overwrite=True)If none of these will install on your machine, running docking on Google Colab gives you a terminal in the browser.
What should you check before you trust the ranking?
Four checks, in order. They take five minutes and they are the difference between a table you can defend and one you cannot.
- Did every ligand actually run? Count files rather than scrolling the log:
ls ligands/*.pdbqt | wc -lagainstls poses/*_out.pdbqt | wc -l. A mismatch means silent failures. - Are any outputs empty?
find poses -name "*_out.pdbqt" -size -1kcatches files that were created but never filled. - Are the top poses in the pocket? Load the two or three best output files over the receptor in PyMOL or your viewer of choice. A compound that scored well by sticking to a surface groove outside the site is a common and embarrassing result, and it is invisible in the numbers. If you are unsure where the site is, settle that with the binding site identification step before the batch run, not after: blind docking is a separate protocol, not a repair for a badly placed box.
- Is the protocol validated at all? Redock the co-crystallised native ligand with the same box and the same settings, then measure the RMSD between the top pose and the crystallographic pose. Do this before you believe anything about the other 39 compounds. If that redocking run does not reproduce the known pose, nothing downstream of it is trustworthy.
Underneath all four sits a limit stated by the developers themselves in the AutoDock Vina FAQ: “The predictive accuracy varies a lot depending on the target, so it makes sense to evaluate AutoDock Vina against your particular target first, if you have known actives, or a bound native ligand structure, before ordering compounds.” Vina scores rank compounds. They do not measure binding affinity, and a difference of 0.2 kcal/mol between two rows is not a result.
What are the common batch docking errors, and how do you fix them?
| What you see | What actually happened | Fix |
|---|---|---|
| Run dies at the first ligand with a file or path error | The --dir target does not exist or is not writable | Create it first with mkdir -p poses and check permissions |
| Fewer output files than input ligands, no obvious error | Some PDBQT files are empty or malformed, so those ligands are skipped | Compare the two wc -l counts, then re-convert the missing ones and inspect the source records |
| One enormous, meaningless pose | A multi-molecule SDF was passed as a single ligand instead of being split | Split with obabel ligands.sdf -O lig.sdf -m and re-prepare |
| Poses look flat or physically impossible | 2D input with no 3D coordinates | Run --gen3d before the PDBQT conversion |
| Larger compounds score badly and sit half outside the site | The box was sized on a small ligand and the big ones do not fit | Re-size the box for the largest compound and re-run the whole set, not just the failures |
| Output names carry an unexpected numeric index | Duplicate input ligand file names collided, so Vina appended an index | Rename inputs uniquely before the run, and keep your SMILES index file |
| The extraction command returns nothing | Wrong directory, or the pattern does not match the REMARK line | Check one file with grep "REMARK VINA RESULT" poses/lig1_out.pdbqt and fix the path or field number |
| The run takes far longer than expected | Exhaustiveness or CPU settings carried over from a single-ligand test | The documented default exhaustiveness is 8, and the tutorials raise it to 32 for difficult cases. Time one ligand first, then multiply |
What comes after you have the ranked table?
The table is a shortlist, not a finding. Take the top three to five compounds forward: draw the interaction diagrams to see which residues each hit contacts, check drug-likeness and ADMET so you are not championing a molecule that could never be dosed, and carry the survivors into a protein-ligand MD simulation to test whether the pose is stable over time. When it is time to write it up, the docking methods section guide lists what an examiner expects you to report, including the box coordinates and the exhaustiveness you used.
For the wider picture of where this sits, see our molecular docking learning path, the docking project ideas for an MSc thesis, and the computational biology skills roadmap.
Frequently asked questions
Can AutoDock Vina dock multiple ligands at once?
Yes, in two different senses. Batch mode docks many ligands one after another and gives one output file per ligand, which is what you want for ranking a compound set. Simultaneous multiple ligand docking places several molecules in the pocket together and is a fragment-based design technique.
How many ligands can I put in one batch run?
There is no documented cap. The practical limit is time, since Vina docks sequentially: total runtime is roughly the per-ligand time multiplied by the number of compounds. Time a single ligand at your chosen exhaustiveness first, then multiply before you start a large set.
Do I need a separate config file for each ligand?
No, and you should not use one. A single config file with one box centre and one box size applies to the whole batch. That shared box is what makes the affinities comparable, so re-centring the box per ligand destroys the ranking you are trying to build.
Where is the docking score stored in the output file?
In the output PDBQT itself, on lines beginning REMARK VINA RESULT. There is one such line per binding mode. The first line in the file corresponds to the top-ranked pose, and its first number is the predicted affinity in kcal/mol.
Is batch docking in Vina the same as virtual screening?
It is the mechanism, not the method. Batch mode gives you a ranked list from a defined ligand set. A screening campaign adds library selection, decoy sets, retrospective validation and hit triage on top of that. Start by getting the batch run and the results table correct.
Should I use PyRx or the command line for a ligand set?
PyRx is easier for a first small set and handles conversion for you. The command line scales better, is reproducible from a script, and gives you an exact record of the parameters to put in your methods section. Most students start with PyRx and move to --batch by the second project.
Batch docking is the step where a docking exercise becomes a docking project. Set the box once, prepare the ligands in a loop, run one command, and extract every score into one sorted file. The parts worth your attention are not the flags: they are the shared grid box, the index that maps file names back to compounds, and the visual check that your top poses are actually in the pocket.
Want the guided, hands-on version?
Our live Molecular Modeling & MD Simulations cohort bootcamp takes you from zero to running real docking and MD workflows, with a portfolio project for your grad-school applications.