diff --git a/cli-auth.c b/cli-auth.c
index 3914c58..0bc55c1 100644
--- a/cli-auth.c
+++ b/cli-auth.c
@@ -40,7 +40,7 @@ void cli_authinitialise() {
 
 /* Send a "none" auth request to get available methods */
 void cli_auth_getmethods() {
-	TRACE(("enter cli_auth_getmethods"))
+	TRACELEVEL((1,"enter cli_auth_getmethods"))
 	CHECKCLEARTOWRITE();
 	buf_putbyte(ses.writepayload, SSH_MSG_USERAUTH_REQUEST);
 	buf_putstring(ses.writepayload, cli_opts.username,
@@ -165,7 +165,7 @@ void recv_msg_userauth_failure() {
 	TRACE(("enter recv_msg_userauth_failure"))
 
 	if (ses.authstate.authdone) {
-		TRACE(("leave recv_msg_userauth_failure, already authdone."))
+		TRACELEVEL((2,"leave recv_msg_userauth_failure, already authdone."))
 		return;
 	}
 
@@ -197,7 +197,7 @@ void recv_msg_userauth_failure() {
 		 * keyboard interactive again */
 		if (cli_ses.lastauthtype == AUTH_TYPE_INTERACT
 				&& !cli_ses.interact_request_received) {
-			TRACE(("setting auth_interact_failed = 1"))
+			TRACELEVEL((1,"setting auth_interact_failed = 1"))
 			cli_ses.auth_interact_failed = 1;
 		}
 #endif
@@ -215,7 +215,7 @@ void recv_msg_userauth_failure() {
 		ses.authstate.failcount++;
 	}
 
-	TRACE(("Methods (len %d): '%s'", methlen, methods))
+	TRACELEVEL((1,"Methods (len %d): '%s'", methlen, methods))
 
 	ses.authstate.authdone=0;
 	ses.authstate.authtypes=0;
@@ -230,23 +230,25 @@ void recv_msg_userauth_failure() {
 	tok = methods; /* tok stores the next method we'll compare */
 	for (i = 0; i <= methlen; i++) {
 		if (methods[i] == '\0') {
-			TRACE(("auth method '%s'", tok))
 #if DROPBEAR_CLI_PUBKEY_AUTH
 			if (strncmp(AUTH_METHOD_PUBKEY, tok,
 				AUTH_METHOD_PUBKEY_LEN) == 0) {
 				ses.authstate.authtypes |= AUTH_TYPE_PUBKEY;
+				TRACELEVEL((1,"auth method '%s' valid", tok))
 			}
 #endif
 #if DROPBEAR_CLI_INTERACT_AUTH
 			if (strncmp(AUTH_METHOD_INTERACT, tok,
 				AUTH_METHOD_INTERACT_LEN) == 0) {
 				ses.authstate.authtypes |= AUTH_TYPE_INTERACT;
+				TRACELEVEL((1,"auth method '%s' valid", tok))
 			}
 #endif
 #if DROPBEAR_CLI_PASSWORD_AUTH
 			if (strncmp(AUTH_METHOD_PASSWORD, tok,
 				AUTH_METHOD_PASSWORD_LEN) == 0) {
 				ses.authstate.authtypes |= AUTH_TYPE_PASSWORD;
+				TRACELEVEL((1,"auth method '%s' valid", tok))
 			}
 #endif
 			tok = &methods[i+1]; /* Must make sure we don't use it after the
@@ -264,7 +266,7 @@ void recv_msg_userauth_success() {
 	/* This function can validly get called multiple times
 	if DROPBEAR_CLI_IMMEDIATE_AUTH is set */
 
-	TRACE(("received msg_userauth_success"))
+	TRACELEVEL((1,"received msg_userauth_success"))
 	/* Note: in delayed-zlib mode, setting authdone here 
 	 * will enable compression in the transport layer */
 	ses.authstate.authdone = 1;
@@ -279,21 +281,25 @@ void recv_msg_userauth_success() {
 int cli_auth_try() {
 
 	int finished = 0;
-	TRACE(("enter cli_auth_try"))
+	TRACELEVEL((1,"enter cli_auth_try"))
 
 	CHECKCLEARTOWRITE();
 	
 	/* Order to try is pubkey, interactive, password.
 	 * As soon as "finished" is set for one, we don't do any more. */
-#if DROPBEAR_CLI_PUBKEY_AUTH
 	if (ses.authstate.authtypes & AUTH_TYPE_PUBKEY) {
+#if DROPBEAR_CLI_PUBKEY_AUTH
+		TRACELEVEL((1,"try  auth method publickey"))
 		finished = cli_auth_pubkey();
 		cli_ses.lastauthtype = AUTH_TYPE_PUBKEY;
-	}
+#else
+		TRACELEVEL((1,"skip auth method publickey (not enabled)"))
 #endif
+	}
 
 #if DROPBEAR_CLI_PASSWORD_AUTH
 	if (!finished && (ses.authstate.authtypes & AUTH_TYPE_PASSWORD)) {
+		TRACELEVEL((1,"try  auth method password"))
 		if (ses.keys->trans.algo_crypt->cipherdesc == NULL) {
 			fprintf(stderr, "Sorry, I won't let you use password auth unencrypted.\n");
 		} else {
@@ -302,10 +308,15 @@ int cli_auth_try() {
 			cli_ses.lastauthtype = AUTH_TYPE_PASSWORD;
 		}
 	}
+#else
+	if (!finished) {
+		TRACELEVEL((1,"skip auth method password (not enabled)"))
+	}
 #endif
 
 #if DROPBEAR_CLI_INTERACT_AUTH
 	if (!finished && (ses.authstate.authtypes & AUTH_TYPE_INTERACT)) {
+		TRACELEVEL((1,"try  AUTH_TYPE_INTERACT"))
 		if (ses.keys->trans.algo_crypt->cipherdesc == NULL) {
 			fprintf(stderr, "Sorry, I won't let you use interactive auth unencrypted.\n");
 		} else {
@@ -316,15 +327,19 @@ int cli_auth_try() {
 			}
 		}
 	}
+#else
+	if (!finished) {
+		TRACELEVEL((1,"skip auth method interact (not enabled)"))
+	}
 #endif
 
-	TRACE(("cli_auth_try lastauthtype %d", cli_ses.lastauthtype))
+	TRACELEVEL((1,"cli_auth_try lastauthtype %d", cli_ses.lastauthtype))
 
 	if (finished) {
-		TRACE(("leave cli_auth_try success"))
+		TRACELEVEL((1,"leave cli_auth_try success"))
 		return DROPBEAR_SUCCESS;
 	}
-	TRACE(("leave cli_auth_try failure"))
+	TRACELEVEL((1,"leave cli_auth_try failure"))
 	return DROPBEAR_FAILURE;
 }
 
diff --git a/cli-runopts.c b/cli-runopts.c
index 4a89ba3..7a78fa7 100644
--- a/cli-runopts.c
+++ b/cli-runopts.c
@@ -93,8 +93,8 @@ static void printhelp() {
 					"-m <MAC list> Specify preferred MACs for packet verification (or '-m help')\n"
 #endif
 					"-V    Version\n"
-#if DEBUG_TRACE
-					"-v    verbose (compiled with DEBUG_TRACE)\n"
+#if DEBUG_LEVEL
+					"-v    verbose level, repeat to increase verbosity\n"
 #endif
 					,DROPBEAR_VERSION, cli_opts.progname,
 #if DROPBEAR_CLI_PUBKEY_AUTH
@@ -291,9 +291,9 @@ void cli_getopts(int argc, char ** argv) {
 					next = &opts.mac_list;
 					break;
 #endif
-#if DEBUG_TRACE
+#if DEBUG_LEVEL
 				case 'v':
-					debug_trace = 1;
+					debug_trace++;
 					break;
 #endif
 				case 'F':
@@ -526,6 +526,11 @@ multihop_passthrough_args() {
 	ret = m_malloc(len);
 	total = 0;
 
+	if (debug_trace)     /* for multihop pass only 1 verbose level */
+	{
+		int written = snprintf(ret+total, len-total, "-v ");
+		total += written;
+	}
 	if (cli_opts.no_hostkey_check)
 	{
 		int written = snprintf(ret+total, len-total, "-y -y ");
diff --git a/common-session.c b/common-session.c
index 99a5470..0055067 100644
--- a/common-session.c
+++ b/common-session.c
@@ -54,11 +54,11 @@ int exitflag = 0; /* GLOBAL */
 void common_session_init(int sock_in, int sock_out) {
 	time_t now;
 
-#if DEBUG_TRACE
+#if DEBUG_LEVEL
 	debug_start_net();
 #endif
 
-	TRACE(("enter session_init"))
+	TRACELEVEL((1,"enter session_init"))
 
 	ses.sock_in = sock_in;
 	ses.sock_out = sock_out;
@@ -277,7 +277,7 @@ static void cleanup_buf(buffer **buf) {
 /* clean up a session on exit */
 void session_cleanup() {
 	
-	TRACE(("enter session_cleanup"))
+	TRACELEVEL((1,"enter session_cleanup"))
 	
 	/* we can't cleanup if we don't know the session state */
 	if (!sessinitdone) {
@@ -375,7 +375,7 @@ static void read_session_identification() {
 		dropbear_exit("Incompatible remote version '%s'", ses.remoteident);
 	}
 
-	TRACE(("remoteident: %s", ses.remoteident))
+	TRACELEVEL((1,"remoteident: %s", ses.remoteident))
 
 }
 
diff --git a/dbutil.c b/dbutil.c
index ab189d2..a56c93e 100644
--- a/dbutil.c
+++ b/dbutil.c
@@ -80,6 +80,8 @@ void (*_dropbear_log)(int priority, const char* format, va_list param)
 						= generic_dropbear_log;
 
 #if DEBUG_TRACE
+int debug_trace = 9;
+#elif DEBUG_LEVEL
 int debug_trace = 0;
 #endif
 
@@ -149,7 +151,7 @@ void dropbear_log(int priority, const char* format, ...) {
 }
 
 
-#if DEBUG_TRACE
+#if DEBUG_LEVEL
 
 static double debug_start_time = -1;
 
@@ -179,10 +181,10 @@ static double time_since_start()
 	return nowf - debug_start_time;
 }
 
-void dropbear_trace(const char* format, ...) {
+void dropbear_tracelevel(int level,const char* format, ...) {
 	va_list param;
 
-	if (!ses.debug_trace) {
+	if (level > debug_trace) {
 		return;
 	}
 
@@ -192,6 +194,18 @@ void dropbear_trace(const char* format, ...) {
 	fprintf(stderr, "\n");
 	va_end(param);
 }
+#endif
+
+#if DEBUG_TRACE
+void dropbear_trace(const char* format, ...) {
+	va_list param;
+
+	va_start(param, format);
+	fprintf(stderr, "TRACE  (%d) %f: ", getpid(), time_since_start());
+	vfprintf(stderr, format, param);
+	fprintf(stderr, "\n");
+	va_end(param);
+}
 
 void dropbear_trace2(const char* format, ...) {
 	static int trace_env = -1;
diff --git a/dbutil.h b/dbutil.h
index 9bcc875..2707f06 100644
--- a/dbutil.h
+++ b/dbutil.h
@@ -50,8 +50,12 @@ void dropbear_trace(const char* format, ...) ATTRIB_PRINTF(1,2);
 void dropbear_trace2(const char* format, ...) ATTRIB_PRINTF(1,2);
 void printhex(const char * label, const unsigned char * buf, int len);
 void printmpint(const char *label, mp_int *mp);
+#endif
+
+#if DEBUG_LEVEL
 void debug_start_net(void);
 extern int debug_trace;
+void dropbear_tracelevel(int level,const char* format, ...) ATTRIB_PRINTF(2,3);
 #endif
 
 char * stripcontrol(const char * text);
diff --git a/debug.h b/debug.h
index 93fbc1f..dfab154 100644
--- a/debug.h
+++ b/debug.h
@@ -43,6 +43,12 @@
 #define DEBUG_TRACE 0
 #endif
 
+/* Use DEBUG_LEVEL for a minimal set of debug messages.
+ * This will add a approx 4kb to the dbclient executble size. */
+#ifndef DEBUG_LEVEL
+#define DEBUG_LEVEL (DEBUG_TRACE)
+#endif
+
 /* All functions writing to the cleartext payload buffer call
  * CHECKCLEARTOWRITE() before writing. This is only really useful if you're
  * attempting to track down a problem */
@@ -71,6 +77,13 @@
 #define TRACE2(X)
 #endif /*DEBUG_TRACE*/
 
+#if DEBUG_LEVEL
+#define TRACELEVEL(X) dropbear_tracelevel X;
+#else 
+#define TRACELEVEL(X) 
+#endif /*DEBUG_LEVEL*/
+
+
 /* To debug with GDB it is easier to run with no forking of child processes.
    You will need to pass "-F" as well. */
 /* #define DEBUG_NOFORK */
