diff --git a/tools/gen-bootstrap.sh b/tools/gen-bootstrap.sh
new file mode 100755
index 0000000000000000000000000000000000000000..ba6554de60b277df8e23e8b146526474926b58cd
--- /dev/null
+++ b/tools/gen-bootstrap.sh
@@ -0,0 +1,195 @@
+#!/bin/bash
+
+# The script is designed for simplification of new bootstrap.snap generation.
+# Just run it in tarantool build directory after updating update.lua (which
+# introduces new data version) and examine its output.
+# The script will try to generate bootstrap.snap in build directory (which is
+# current directory by default), and in case of success will offer to copy the
+# file to the source tree.
+# Run --help for more options.
+# The manual instruction by which the script was created is available here:
+MANUAL_LINK="https://github.com/tarantool/tarantool/wiki/How-to-generate-new-bootstrap-snapshot"
+# Now the script does the following:
+ACTIONS=( "rebuild tarantool.")
+ACTIONS+=("run box.cfg{} box.internal.bootstrap() by tarantool in a clean dir.")
+ACTIONS+=("take the latest snapshot file an rename it to bootstrap.snap file.")
+ACTIONS+=("edit the file and change line with VClock to an empty set: {}.")
+
+set -eu -o pipefail
+
+error() {
+   echo "$@" 1>&2
+   exit 1
+}
+
+if ! getopt -V >/dev/null 2>&1; then
+    error "getopt must be (installed)."
+fi
+
+if ! xxd -v >/dev/null 2>&1; then
+    error "xxd must be installed."
+fi
+
+if ! cmake --version >/dev/null 2>&1; then
+    error "cmake must be installed."
+fi
+
+usage() {
+    echo ""
+    echo "Usage:"
+    echo " $0 [options]"
+    echo ""
+    echo "Options:"
+    echo " -b, --builddir       Set build directory of tarantool"
+    echo "                       (default: current directory)"
+    echo " -s, --sourcedir      Set source directory of tarantool"
+    echo "                       (default: parsed from CMakeCache.txt)"
+    echo " -t, --tempdir        Set temporary directory"
+    echo "                       (default: <build dir>/gen-bootstrap-tmp)"
+    echo " -a, --autobuild      Build tarantool before generation (default)."
+    echo " -A, --no-autobuild   Don't build tarantool before generation."
+    echo " -h, --help           Show this help and exit"
+    exit 0
+}
+
+shortopts="b:s:t:aAh"
+longopts="builddir:,sourcedir:,tempdir:,autobuild,no-autobuild,help"
+
+builddir=.
+sourcedir=
+tempdir=
+tempdir_default_name=gen-bootstrap-tmp
+autobuild=true
+
+opts=$(getopt --options "$shortopts" --long "$longopts" --name "$0" -- "$@")
+eval set -- "$opts"
+
+while true; do
+    case "$1" in
+        -b | --builddir ) builddir=$2; shift 2;;
+        -s | --sourcedir ) sourcedir=$2; shift 2;;
+        -t | --tempdir ) tempdir=$2; shift 2;;
+        -a | --autobuild ) autobuild=true; shift 1;;
+        -A | --no-autobuild ) autobuild=false; shift 1;;
+        -h | --help ) usage; shift 1;;
+        -- ) shift; break;;
+        * ) error "Failed to parse options";;
+    esac
+done
+if [[ $# -gt 0 ]]; then
+    error "Unrecognized command: $@"
+fi
+
+if ! [[ -d "$builddir" ]]; then
+    error "Build directory is not a directory!"
+fi
+
+builddir=$(realpath "$builddir")
+
+if [[ -z "$tempdir" ]]; then
+    tempdir="$builddir/$tempdir_default_name"
+fi
+
+tempdir=$(realpath "$tempdir")
+
+if [[ -z "$sourcedir" ]]; then
+    if ! [[ -f "$builddir/CMakeCache.txt" ]]; then
+        error "Tarantool build was not found in '$builddir'"
+    fi
+    line=$(grep "^tarantool_SOURCE_DIR:STATIC=" "$builddir/CMakeCache.txt")
+    if ! [[ "$line" =~ ^tarantool_SOURCE_DIR:STATIC=(.*)$ ]]; then
+        error "Tarantool build was not found in '$builddir'"
+    fi
+    sourcedir="${BASH_REMATCH[1]}"
+fi
+
+sourcedir=$(realpath "$sourcedir")
+source_bootstrap="$sourcedir/src/box/bootstrap.snap"
+
+if ! [[ -f "$source_bootstrap" ]]; then
+    error "File $source_bootstrap was not found. Wrong sourcedir?"
+fi
+
+if [[ -f "$tempdir" ]]; then
+    error "Regular file $tempdir was found, has no idea what to do, exiting."
+fi
+
+if [[ -d "$tempdir" ]]; then
+    echo "Folder $tempdir was found, it seems that previous run was failed."
+    read -p "Drop the folder and proceed [Yn]?" yn
+    case ${yn:-y} in
+        [Yy]* ) rm -r "$tempdir";;
+        [Nn]* ) echo "OK, exiting."; exit 0;;
+        * ) error "Wrong answer.";;
+    esac
+fi
+
+cd "$builddir"
+tnt_binary="$builddir/src/tarantool"
+
+if [[ $autobuild = true ]]; then
+    if ! cmake --build . -j; then
+        error "Failed to rebuild tarantool."
+    fi
+else
+    unset 'ACTIONS[0]'
+fi
+
+if ! "$tnt_binary" --version >/dev/null 2>&1; then
+    error "Tarantool binary was not found ($tnt_binary)."
+fi
+
+mkdir "$tempdir"
+cd "$tempdir"
+
+if ! "$tnt_binary" -e "box.cfg{} box.internal.bootstrap() os.exit(0)"; then
+    error "Failed to run script by tarantool, exiting."
+fi
+
+mv $(ls *.snap | sort | tail -n 1) ./bootstrap.snap
+
+# Clear VClock field of the file.
+# Actually all the code below does only simple command:
+# sed -i '0,/^VClock: {.*}$/{s//VClock: {}/}' ./bootstrap.snap
+# .. but instead let's use canonical approach for patching binary files!
+if ! head -n 6 ./bootstrap.snap | egrep "VClock: {.*}" > /dev/null; then
+    error "Failed to patch VClock: is was not found."
+fi
+head -n 6 ./bootstrap.snap > old_header.txt
+head -n 6 ./bootstrap.snap | sed "s/VClock: {.*}/VClock: {}/" > new_header.txt
+bootstrap_hex=$(xxd -p bootstrap.snap | tr -d '\n')
+old_header_hex=$(xxd -p old_header.txt | tr -d '\n')
+new_header_hex=$(xxd -p new_header.txt | tr -d '\n')
+if ! [[ ${bootstrap_hex} =~ ^${old_header_hex}(.*)$ ]]; then
+    error "Failed to patch VClock: hex patch failed."
+fi
+echo ${new_header_hex}${BASH_REMATCH[1]} | xxd -p -r > ./bootstrap.snap
+
+mv ./bootstrap.snap "$builddir/bootstrap.snap"
+cd "$builddir"
+rm -r "$tempdir"
+
+echo ""
+echo "What was done:"
+for action in "${ACTIONS[@]}"; do
+    echo "* ${action}"
+done
+echo "Please compare with manual instruction:"
+echo "$MANUAL_LINK"
+echo ""
+
+copy_to_source_tree=false
+echo "It seems that ./bootstrap.snap was successfully generated."
+read -p "Copy file to the source tree ('$source_bootstrap') [yN]?" yn
+case ${yn:-n} in
+    [Yy]* ) copy_to_source_tree=true;;
+    [Nn]* ) copy_to_source_tree=false;;
+    * ) error "Wrong answer, exiting";;
+esac
+
+if [[ $copy_to_source_tree = true ]]; then
+    cp ./bootstrap.snap "$source_bootstrap"
+    echo "Copied to $source_bootstrap"
+else
+    echo "Enjoy bootstrap.snap"
+fi