diff --git a/client/djrandom_client/client.py b/client/djrandom_client/client.py
index db66af34c9fc2acf739aa48b4dd33194d04d0bdf..f7ee79a3289600fcf8064c61cc2461f380e9a8f0 100644
--- a/client/djrandom_client/client.py
+++ b/client/djrandom_client/client.py
@@ -52,8 +52,12 @@ class FullScan(threading.Thread):
 
 
 def run_client(server_url, music_dir, api_key, run_once, bwlimit, enable_watcher):
-    if bwlimit:
-        throttle.set_rate_limit(int(bwlimit))
+    # Warn if we're running without a bandwidth limit.
+    bwlimit = int(bwlimit)
+    if bwlimit <= 0:
+        log.warn('Running without a bandwidth limit!')
+    else:
+        throttle.set_rate_limit(bwlimit)
 
     # Warn on this condition, but don't die -- the directory might exist later!
     if not os.path.isdir(music_dir):
@@ -123,15 +127,16 @@ def main():
     parser.add_option('--server_url',
                       default='https://djrandom.incal.net/receiver',
                       help='URL to the API endpoint')
-    parser.add_option('--bwlimit', type='int',
-                      help='Bandwidth limit (in KBps, default unlimited)')
+    parser.add_option('--bwlimit', type='int', default=0,
+                      help='Upload bandwidth limit, kilobytes/s (default: '
+                      'unlimited)')
     parser.add_option('--no_realtime_watch', action='store_true',
                       help='Monitor music_dir in realtime')
     daemonize.add_standard_options(parser)
     utils.read_config_defaults(
-        parser, os.path.join(os.getenv('HOME'), '.djrandom.conf'))
+        parser, os.path.expanduser('~/.djrandom.conf'))
     parser.set_default(
-        'pidfile', os.path.join(os.getenv('HOME'), '.djrandom.pid'))
+        'pidfile', os.path.expanduser('~/.djrandom.pid'))
     opts, args = parser.parse_args()
     if not opts.api_key:
         parser.error('You must specify an API Key')
diff --git a/client/djrandom_client/test/test_client.py b/client/djrandom_client/test/test_client.py
index 07789d1e0d521ac21b4b6e583eef998e5fd3a730..90b1ed6f2e804d73a03ea21095400ac201411062 100644
--- a/client/djrandom_client/test/test_client.py
+++ b/client/djrandom_client/test/test_client.py
@@ -1,6 +1,9 @@
 import mox
+import os
 import unittest
+import shutil
 import sys
+import tempfile
 import time
 import Queue
 from djrandom_client import client
@@ -65,14 +68,7 @@ class FullScanTest(mox.MoxTestBase):
         self.assertRaises(EndTest, fs.run)
 
 
-class ClientOptionsTest(mox.MoxTestBase):
-
-    def setUp(self):
-        mox.MoxTestBase.setUp(self)
-        self.mox.StubOutWithMock(utils, 'read_config_defaults')
-        utils.read_config_defaults(mox.IgnoreArg(), mox.IsA(str))
-        self.mox.StubOutWithMock(utils, 'check_version')
-        self.mox.StubOutWithMock(daemonize, 'daemonize')
+class ClientRunner(object):
 
     def _Run(self, args, expect_success=True):
         try:
@@ -86,6 +82,55 @@ class ClientOptionsTest(mox.MoxTestBase):
             'execution with args: "%s" failed (status %s, expected %s)' % (
                 ' '.join(args), success, expect_success))
 
+
+class ClientWithConfigFileTest(ClientRunner, mox.MoxTestBase):
+
+    def setUp(self):
+        mox.MoxTestBase.setUp(self)
+        self.tmpdir = tempfile.mkdtemp()
+        self.old_expanduser = os.path.expanduser
+        def _expanduser(p):
+            if p.startswith('~/'):
+                return os.path.join(self.tmpdir, p[2:])
+            else:
+                return p
+        os.path.expanduser = _expanduser
+
+    def tearDown(self):
+        mox.MoxTestBase.tearDown(self)
+        shutil.rmtree(self.tmpdir)
+        os.path.expanduser = self.old_expanduser
+
+    def test_run_options_from_config(self):
+        config_file = os.path.join(self.tmpdir, '.djrandom.conf')
+        with open(config_file, 'w') as fd:
+            fd.write('api_key = KEY\nbwlimit = 10\n')
+
+        self.mox.StubOutWithMock(utils, 'check_version')
+        utils.check_version()
+
+        self.mox.StubOutWithMock(daemonize, 'daemonize')
+        daemonize.daemonize(mox.IgnoreArg(),
+                            client.run_client,
+                            CompareTuple(mox.IsA(str),
+                                         mox.IsA(str),
+                                         'KEY',
+                                         None, 10, True))
+
+        self.mox.ReplayAll()
+        self._Run([])
+
+
+class ClientOptionsTest(ClientRunner, mox.MoxTestBase):
+
+    def setUp(self):
+        mox.MoxTestBase.setUp(self)
+        self.mox.StubOutWithMock(utils, 'read_config_defaults')
+        utils.read_config_defaults(mox.IgnoreArg(), mox.IsA(str))
+        self.mox.StubOutWithMock(utils, 'check_version')
+        self.mox.StubOutWithMock(daemonize, 'daemonize')
+
+
     def test_client_needs_api_key(self):
         self.mox.ReplayAll()
         self._Run([], False)
@@ -101,7 +146,7 @@ class ClientOptionsTest(mox.MoxTestBase):
                             CompareTuple(mox.IsA(str),
                                          mox.IsA(str),
                                          'KEY',
-                                         None, None, True))
+                                         None, 0, True))
 
         self.mox.ReplayAll()
         self._Run(['--api_key=KEY'])