diff --git a/CMakeLists.txt b/CMakeLists.txt
index ad7536c0841cad156334f581497398cdd06098fd..d7d847b6f54f901ee0069216fcbc55aa35d65e88 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -25,7 +25,7 @@ FIND_PACKAGE(MX)
 FIND_PACKAGE(OpenMX)
 FIND_PACKAGE(Dolphin)
 FIND_PACKAGE(NDS2Client)
-FIND_PACKAGE(Boost COMPONENTS system)
+FIND_PACKAGE(Boost COMPONENTS filesystem system)
 FIND_PACKAGE(RapidJSON)
 FIND_PACKAGE(RPC)
 FIND_PACKAGE(libcds-pubsub)
diff --git a/NEWS b/NEWS
index ada64cd4423e7446bd520e34bb641c9a28b4d5ad..d5efae48c517095a86bbf78d986503c1a865b63f 100644
--- a/NEWS
+++ b/NEWS
@@ -17,9 +17,16 @@ Changes for 4.0  (NOT YET RELEASED)
 - Implemented a standalone_edc.
    - An edcu as a regular program, not a non-rt model.
    - Can record data into multiple types (short, int, float, double)
-- Implemented fix for FRX 13791
+- Implemented fix for FRS 13791
    - Increase the number of connections allowed on a daqd circular buffer past 32.
    - Generalize the data structure to allow changing the max number easier.  Currently set to 128.
+- Updated the nds process
+   - run dir defaults to /var/run/nds
+   - the name of the socket has changed from pipe to daqd_socket
+   - the command line is changed to specifying the run dir instead of the pipe/socket filename
+   - ie nds --rundir /var/run/nds
+     - gives a jobs dir of /var/run/nds/jobs and a socket at /var/run/nds/daqd_socket
+   - the nds process will attempt to create the 'jobs' directory if it does not exist
 ==================================================================================================
 Changes for 3.6  (NOT YET RELEASED)
 ==================================================================================================
diff --git a/src/daqd/daqd.hh b/src/daqd/daqd.hh
index 58b21a1ae2159e4bf155c232cfdaf5017074216b..81e54385ca760dd3ee39d4a55559370fa961b44a 100644
--- a/src/daqd/daqd.hh
+++ b/src/daqd/daqd.hh
@@ -227,6 +227,12 @@ private:
     parameter_set _params;
 
 public:
+    static std::string
+    default_nds_jobs_dir( )
+    {
+        return "/var/run/nds";
+    }
+
     daqd_c( )
         : _configuration_number( 0 ), b1( 0 ), producer1( 0 ),
           num_channels( 0 ), num_active_channels( 0 ),
@@ -245,8 +251,9 @@ public:
           shutting_down( 0 ), num_listeners( 0 ), block_size( 0 ),
           thread_stack_size( 10 * 1024 * 1024 ), config_file_name( 0 ),
           offline_disabled( 0 ), profile( (char*)"main" ),
-          do_scan_frame_reads( 0 ), fsd( 1 ), science_fsd( 1 ), nds_jobs_dir( ),
-          detector_name( "" ), detector_prefix( "" ), detector_longitude( 0. ),
+          do_scan_frame_reads( 0 ), fsd( 1 ), science_fsd( 1 ),
+          nds_jobs_dir( default_nds_jobs_dir( ) ), detector_name( "" ),
+          detector_prefix( "" ), detector_longitude( 0. ),
           detector_latitude( 0. ), detector_elevation( .0 ),
           detector_arm_x_azimuth( .0 ), detector_arm_y_azimuth( .0 ),
           detector_arm_x_altitude( .0 ), detector_arm_y_altitude( .0 ),
diff --git a/src/daqd/net_writer.cc b/src/daqd/net_writer.cc
index b3930dc0416f9a76672b7e00d3cc9c4b130660b4..fc374b4a5895f7efe7a7b6a5984395f00ca6c50e 100644
--- a/src/daqd/net_writer.cc
+++ b/src/daqd/net_writer.cc
@@ -81,7 +81,7 @@ net_writer_c::send_files( void )
     sprintf( jobn_buf, "%ld", job_num );
     string spec_filename = daqd.nds_jobs_dir + "/jobs/" + jobn_buf;
     string pipe = daqd.nds_jobs_dir +
-        "/pipe"; // unix domain socket communication endpoint
+        "/daqd_socket"; // unix domain socket communication endpoint
 
     // connect UNIX socket on pipe
     int                socketfd;
@@ -516,8 +516,8 @@ net_writer_c::producer( )
                     &prop );
 
                 //	cerr << "net_writer_c::producer(): put() of " <<
-                //source_buffptr -> block_prop (nb) -> bytes << " bytes" <<
-                //endl;
+                // source_buffptr -> block_prop (nb) -> bytes << " bytes" <<
+                // endl;
                 if ( nb16th == 0xf )
                     break;
             }
@@ -552,8 +552,8 @@ net_writer_c::producer( )
                     &prop );
 
                 //	cerr << "net_writer_c::producer(): put() of " <<
-                //source_buffptr -> block_prop (nb) -> bytes << " bytes" <<
-                //endl;
+                // source_buffptr -> block_prop (nb) -> bytes << " bytes" <<
+                // endl;
             }
             source_buffptr->unlock( cnum );
         }
@@ -700,7 +700,7 @@ net_writer_c::consumer( )
                         dec_vec[ i ].vec_bps / dec_vec[ i ].vec_rate;
                     //	      DEBUG1(cerr <<
                     //"net_writer_c::consumer(decimation): averaging " <<
-                    //samples_per_point << " samples" << endl);
+                    // samples_per_point << " samples" << endl);
                     DEBUG1( cerr
                             << "net_writer_c::consumer(decimation) decimating"
                             << samples_per_point << " samples" << endl );
diff --git a/src/daqd/tests/test_daqd_nds.sh.in b/src/daqd/tests/test_daqd_nds.sh.in
index 272b41d7adeb08487bdc2d02ebbc718917e6060f..258101a9050d13cb7bb627f7ce089fc6a8794440 100644
--- a/src/daqd/tests/test_daqd_nds.sh.in
+++ b/src/daqd/tests/test_daqd_nds.sh.in
@@ -82,7 +82,7 @@ mkdir "$TDIR/logs"
 mkdir "$TDIR/frames"
 mkdir "$TDIR/frames/full"
 mkdir "$TDIR/frames/nds"
-mkdir "$TDIR/frames/nds/jobs"
+#mkdir "$TDIR/frames/nds/jobs"
 
 echo "Ini dir = $TDIR/ini_files"
 
@@ -103,7 +103,7 @@ PID_DAQD=$!
 sleep 5
 echo "Starting the nds service"
 
-"$NDS" "$TDIR/frames/nds/pipe" > "$TDIR/logs/nds" &
+"$NDS" --rundir "$TDIR/frames/nds" > "$TDIR/logs/nds" &
 PID_NDS=$!
 
 echo "Sleeping to allow the daq to finish startup"
diff --git a/src/nds/CMakeLists.txt b/src/nds/CMakeLists.txt
index 5bb7e777d67503b534e73d13aa965fb2051e8e11..356a947811e5176936ee2620d0ca7bd68586cf9b 100644
--- a/src/nds/CMakeLists.txt
+++ b/src/nds/CMakeLists.txt
@@ -51,8 +51,12 @@ target_include_directories(nds PRIVATE
     ${CMAKE_CURRENT_SOURCE_DIR}/framelib/src
     ${CMAKE_CURRENT_SOURCE_DIR}/framelib/src/zlib
     ${CMAKE_CURRENT_SOURCE_DIR}/../include
+    ${Boost_INCLUDE_DIRS}
 )
-target_link_libraries(nds PRIVATE ldastools::framecpp)
+target_link_libraries(nds PRIVATE
+        args
+        ldastools::framecpp
+        ${Boost_LIBRARIES})
 
 install(TARGETS nds DESTINATION bin)
 
diff --git a/src/nds/main.cc b/src/nds/main.cc
index 437c8f21d09c112708029fc0082095e6eac55903..cf7b8315de0c5d6d805d0d7cfcaa06b64e272b4d 100644
--- a/src/nds/main.cc
+++ b/src/nds/main.cc
@@ -1,14 +1,34 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <iostream>
+#include <sstream>
 #include <unistd.h>
 #include "nds.hh"
-//#include "framecpp/dictionary.hh"
+#include "args.h"
+
+#include <boost/filesystem.hpp>
 
 using namespace CDS_NDS;
+namespace fs = boost::filesystem;
 
-std::string programname; // Set to the program's executable name during run time
+struct NDSConfigOpts
+{
+    fs::path run_dir{};
+    fs::path log_path{};
+    bool     exit{ false };
 
+    fs::path
+    socket_path( ) const
+    {
+        return run_dir / "daqd_socket";
+    }
+
+    fs::path
+    jobs_dir( ) const
+    {
+        return run_dir / "jobs";
+    };
+};
 //
 // Set log level 2 in the production system
 //
@@ -18,53 +38,95 @@ int nds_log_level = 4; // Controls volume of log messages
 int _debug = 4; // Controls volume of the debugging messages that is printed out
 #endif
 
-// FrameCPP::Dictionary *dict = FrameCPP::library.getCurrentVersionDictionary();
-//
+NDSConfigOpts
+parse_args( int argc, char* argv[] )
+{
+    NDSConfigOpts opts;
+
+    const char* log_dest = nullptr;
+    const char* run_dir = nullptr;
+    const char* default_run_dir = "/var/run/nds";
+
+    auto arg_parser = args_create_parser(
+        "The archive data retrieval service for daqd data" );
+    args_add_string_ptr( arg_parser,
+                         'l',
+                         ARGS_NO_LONG,
+                         "filename",
+                         "Send log information to the given file",
+                         &log_dest,
+                         nullptr );
+    args_add_string_ptr(
+        arg_parser,
+        'd',
+        "rundir",
+        "path",
+        "Directory that the jobs dir and daqd_socket reside in",
+        &run_dir,
+        default_run_dir );
+    opts.exit = ( args_parse( arg_parser, argc, argv ) < 1 );
+    args_destroy( &arg_parser );
+
+    opts.run_dir = run_dir;
+    opts.log_path = ( log_dest ? log_dest : "" );
+    return opts;
+}
 
 void
-usage( int c )
+setup_logging( const std::string& programname, const NDSConfigOpts& opts )
 {
-    system_log( 1, "nds usage: nds [-l logfilename ] <pipe file name>" );
-    exit( c );
+    openlog( programname.c_str( ), LOG_PID | LOG_CONS, LOG_USER );
+    if ( !opts.log_path.empty( ) )
+    {
+        FILE* f = freopen( opts.log_path.c_str( ), "w", stdout );
+        setvbuf( stdout, NULL, _IOLBF, 0 );
+        stderr = stdout;
+    }
 }
 
-int
-parse_args( int argc, char* argv[] )
+void
+ensure_jobs_dir( const NDSConfigOpts& opts )
 {
-    int          c;
-    extern char* optarg;
-    extern int   optind;
+    namespace fs = boost::filesystem;
 
-    while ( ( c = getopt( argc, argv, "Hhl:" ) ) != -1 )
+    fs::path jobs_dir = opts.jobs_dir( );
+    if ( fs::exists( jobs_dir ) )
     {
-        FILE* f;
-        switch ( c )
+        if ( fs::is_directory( jobs_dir ) )
         {
-        case 'H':
-        case 'h':
-            usage( 0 );
-            break;
-        case 'l':
-            f = freopen( optarg, "w", stdout );
-            setvbuf( stdout, NULL, _IOLBF, 0 );
-            stderr = stdout;
-            break;
-        default:
-            usage( 1 );
+            return;
         }
+        std::ostringstream os;
+        os << "The jobs directory '" << jobs_dir
+           << "' exists and is not a directory";
+        throw std::runtime_error( os.str( ) );
     }
-    return optind;
+    std::cout << "The jobs directory does not exist, attempting to create '"
+              << jobs_dir << "'" << std::endl;
+    fs::create_directories( jobs_dir );
 }
 
 int
 main( int argc, char* argv[] )
 {
-    programname = Nds::basename( argv[ 0 ] );
-    openlog( programname.c_str( ), LOG_PID | LOG_CONS, LOG_USER );
-    int optind = parse_args( argc, argv );
-    if ( argc != optind + 1 )
-        usage( 1 );
-    Nds nds( argv[ optind ] );
+    auto opts = parse_args( argc, argv );
+    if ( opts.exit )
+    {
+        return 1;
+    }
+
+    std::string programname = Nds::basename( argv[ 0 ] );
+    setup_logging( programname, opts );
+
+    std::string socket_path = opts.socket_path( ).string( );
+    std::cout << "NDS server starting\nRun dir = " << opts.run_dir;
+    std::cout << "\nSocket path = " << socket_path;
+    std::cout << "\nJobs dir = " << opts.jobs_dir( ) << std::endl;
+
+    fs::current_path( opts.run_dir );
+    ensure_jobs_dir( opts );
+
+    Nds nds( socket_path );
     int res = nds.run( );
     return res;
 }