diff --git a/CHANGES.txt b/CHANGES.txt
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,5 +1,8 @@
 Changelog for Shake (* = breaking change)
 
+0.17.4, released 2019-01-10
+    Add shakeProfileDatabase to generate profile information
+    Don't suggest -qb (irrelevant with -qg)
 0.17.3, released 2018-12-04
     #632, remove O(n^2) behaviour when constructing user rules
     In diagnostic mode, show the number of actions/rules/user rules
diff --git a/LICENSE b/LICENSE
--- a/LICENSE
+++ b/LICENSE
@@ -1,4 +1,4 @@
-Copyright Neil Mitchell 2011-2018.
+Copyright Neil Mitchell 2011-2019.
 All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
diff --git a/docs/Manual.md b/docs/Manual.md
--- a/docs/Manual.md
+++ b/docs/Manual.md
@@ -288,7 +288,7 @@
 
 Now you can run a build by typing `stack exec ./build.sh` on Linux, or `stack exec build.bat` on Windows. On Linux you may want to alias `build` to `stack exec ./build.sh`. For the rest of this document we will assume `build` runs the build system.
 
-_Warning:_ You should not use the `-threaded` for GHC 7.6 or below because of a [GHC bug](https://ghc.haskell.org/trac/ghc/ticket/7646). If you do turn on `-threaded`, you should include `-qg -qb` in `-with-rtsopts`.
+_Warning:_ You should not use the `-threaded` for GHC 7.6 or below because of a [GHC bug](https://ghc.haskell.org/trac/ghc/ticket/7646). If you do turn on `-threaded`, you should include `-qg` in `-with-rtsopts`.
 
 #### Command line flags
 
diff --git a/shake.cabal b/shake.cabal
--- a/shake.cabal
+++ b/shake.cabal
@@ -1,13 +1,13 @@
 cabal-version:      >= 1.18
 build-type:         Simple
 name:               shake
-version:            0.17.3
+version:            0.17.4
 license:            BSD3
 license-file:       LICENSE
 category:           Development, Shake
 author:             Neil Mitchell <ndmitchell@gmail.com>
 maintainer:         Neil Mitchell <ndmitchell@gmail.com>
-copyright:          Neil Mitchell 2011-2018
+copyright:          Neil Mitchell 2011-2019
 synopsis:           Build system library, like Make, but more accurate dependencies.
 description:
     Shake is a Haskell library for writing build systems - designed as a
@@ -30,7 +30,7 @@
     (e.g. compiler version).
 homepage:           https://shakebuild.com
 bug-reports:        https://github.com/ndmitchell/shake/issues
-tested-with:        GHC==8.6.1, GHC==8.4.4, GHC==8.2.2, GHC==8.0.2, GHC==7.10.3, GHC==7.8.4, GHC==7.6.3, GHC==7.4.2
+tested-with:        GHC==8.6.3, GHC==8.4.4, GHC==8.2.2, GHC==8.0.2, GHC==7.10.3, GHC==7.8.4, GHC==7.6.3, GHC==7.4.2
 extra-doc-files:
     CHANGES.txt
     README.md
@@ -198,7 +198,7 @@
     ghc-options: -rtsopts
     -- GHC bug 7646 means -threaded causes errors
     if impl(ghc >= 7.8)
-        ghc-options: -threaded "-with-rtsopts=-I0 -qg -qb"
+        ghc-options: -threaded "-with-rtsopts=-I0 -qg"
     build-depends:
         base == 4.*,
         binary,
diff --git a/src/Development/Shake.hs b/src/Development/Shake.hs
--- a/src/Development/Shake.hs
+++ b/src/Development/Shake.hs
@@ -169,7 +169,7 @@
 --
 --   For large build systems the choice of GHC flags can have a significant impact. We recommend:
 --
--- > ghc --make MyBuildSystem -threaded -rtsopts "-with-rtsopts=-I0 -qg -qb"
+-- > ghc --make MyBuildSystem -threaded -rtsopts "-with-rtsopts=-I0 -qg"
 --
 --   * @-rtsopts@: Allow the setting of further GHC options at runtime.
 --
@@ -180,7 +180,7 @@
 --     can cause a race condition in build systems that write files then read them. Omitting @-threaded@ will
 --     still allow your 'cmd' actions to run in parallel, so most build systems will still run in parallel.
 --
---   * With GHC 7.8 and later you may add @-threaded@, and pass the options @-qg -qb@ to @-with-rtsopts@
+--   * With GHC 7.8 and later you may add @-threaded@, and pass the options @-qg@ to @-with-rtsopts@
 --     to disable parallel garbage collection. Parallel garbage collection in Shake
 --     programs typically goes slower than sequential garbage collection, while occupying many cores that
 --     could be used for running system commands.
diff --git a/src/Development/Shake/Database.hs b/src/Development/Shake/Database.hs
--- a/src/Development/Shake/Database.hs
+++ b/src/Development/Shake/Database.hs
@@ -20,6 +20,7 @@
     shakeOneShotDatabase,
     shakeRunDatabase,
     shakeLiveFilesDatabase,
+    shakeProfileDatabase,
     shakeErrorsDatabase,
     shakeRunAfter
     ) where
@@ -100,6 +101,13 @@
     withOpen use "shakeLiveFilesDatabase" id $ \_ ->
         liveFilesState s
 
+-- | Given a 'ShakeDatabase', generate profile information to the given file about the latest run.
+--   See 'shakeReport' for the types of file that can be generated.
+shakeProfileDatabase :: ShakeDatabase -> FilePath -> IO ()
+shakeProfileDatabase (ShakeDatabase use s) file =
+    withOpen use "shakeProfileDatabase" id $ \_ ->
+        profileState s file
+
 -- | Given a 'ShakeDatabase', what files did the execution reach an error on last time.
 --   Some special considerations when using this function:
 --
@@ -125,7 +133,7 @@
 -- | Given an open 'ShakeDatabase', run both whatever actions were added to the 'Rules',
 --   plus the list of 'Action' given here. Returns the results from the explicitly passed
 --   actions along with a list of actions to run after the database was closed, as added with
---   'runAfter' and 'removeFilesAfter'.
+--   'Development.Shake.runAfter' and 'Development.Shake.removeFilesAfter'.
 shakeRunDatabase :: ShakeDatabase -> [Action a] -> IO ([a], [IO ()])
 shakeRunDatabase (ShakeDatabase use s) as =
     withOpen use "shakeRunDatabase" (\o -> o{openRequiresReset=True}) $ \Open{..} -> do
diff --git a/src/Development/Shake/Internal/Core/Run.hs b/src/Development/Shake/Internal/Core/Run.hs
--- a/src/Development/Shake/Internal/Core/Run.hs
+++ b/src/Development/Shake/Internal/Core/Run.hs
@@ -9,6 +9,7 @@
     run,
     shakeRunAfter,
     liveFilesState,
+    profileState,
     errorsState
     ) where
 
@@ -242,6 +243,11 @@
 liveFilesState RunState{..} = do
     database <- readVar databaseVar
     liveFiles database
+
+profileState :: RunState -> FilePath -> IO ()
+profileState RunState{..} file = do
+    database <- readVar databaseVar
+    writeProfile file database
 
 liveFiles :: Database -> IO [FilePath]
 liveFiles database = do
diff --git a/src/Test/Database.hs b/src/Test/Database.hs
--- a/src/Test/Database.hs
+++ b/src/Test/Database.hs
@@ -48,6 +48,8 @@
     live <- shakeLiveFilesDatabase db
     sort live === ["a.in","a.out"]
 
+    shakeProfileDatabase db "-"
+
     -- check that parallel runs blow up, and that we can throw async exceptions to kill it
     assertWithin 10 $ do
         threads <- newBarrier
diff --git a/src/Test/Docs.hs b/src/Test/Docs.hs
--- a/src/Test/Docs.hs
+++ b/src/Test/Docs.hs
@@ -352,7 +352,7 @@
     ,"1m25s (15%)"
     ,"3m12s (82%)"
     ,"getPkgVersion $ GhcPkgVersion \"shake\""
-    ,"ghc --make MyBuildSystem -threaded -rtsopts \"-with-rtsopts=-I0 -qg -qb\""
+    ,"ghc --make MyBuildSystem -threaded -rtsopts \"-with-rtsopts=-I0 -qg\""
     ,"# command-name (for file-name)"
     ,"<i>build rules</i>"
     ,"<i>actions</i>"
