diff --git a/src/executor/CMakeLists.txt b/src/executor/CMakeLists.txt
index 9aa9e3ebfc6c1a25aaac977e7a80614e076b9028..227104dc12b464b8e757e010716125d599465854 100644
--- a/src/executor/CMakeLists.txt
+++ b/src/executor/CMakeLists.txt
@@ -45,6 +45,7 @@ add_library(
     SetExecutor.cpp
     FindExecutor.cpp
     MatchExecutor.cpp
+    DeleteVertexExecutor.cpp
 )
 add_dependencies(
     graph_obj
diff --git a/src/executor/DeleteVertexExecutor.cpp b/src/executor/DeleteVertexExecutor.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..f778d0143d6b50f59b216dbbafff8d805bfa7749
--- /dev/null
+++ b/src/executor/DeleteVertexExecutor.cpp
@@ -0,0 +1,113 @@
+/* Copyright (c) 2019 vesoft inc. All rights reserved.
+ *
+ * This source code is licensed under Apache 2.0 License,
+ * attached with Common Clause Condition 1.0, found in the LICENSES directory.
+ */
+
+#include "graph/DeleteVertexExecutor.h"
+#include "storage/client/StorageClient.h"
+
+namespace nebula {
+namespace graph {
+
+DeleteVertexExecutor::DeleteVertexExecutor(Sentence *sentence,
+                                           ExecutionContext *ectx) : Executor(ectx) {
+    sentence_ = static_cast<DeleteVertexSentence*>(sentence);
+}
+
+Status DeleteVertexExecutor::prepare() {
+    auto ovalue = sentence_->vid()->eval();
+    auto v = ovalue.value();
+    if (!Expression::isInt(v)) {
+        return Status::Error("Vertex ID should be of type integer");
+    }
+    vid_ = Expression::asInt(v);
+    return Status::OK();
+}
+
+void DeleteVertexExecutor::execute() {
+    GraphSpaceID space = ectx()->rctx()->session()->space();
+    // TODO(zlcook) Get edgeKes of a vertex by Go
+    auto future = ectx()->storage()->getEdgeKeys(space, vid_);
+    auto *runner = ectx()->rctx()->runner();
+    auto cb = [this] (auto &&resp) {
+        if (!resp.ok()) {
+            DCHECK(onError_);
+            onError_(Status::Error("Internal Error"));
+            return;
+        }
+        auto rpcResp = std::move(resp).value();
+        std::vector<storage::cpp2::EdgeKey> allEdges;
+        for (auto& edge : *rpcResp.get_edge_keys()) {
+            auto reverseEdge = storage::cpp2::EdgeKey(apache::thrift::FragileConstructor::FRAGILE,
+                                                      edge.get_dst(),
+                                                      -(edge.get_edge_type()),
+                                                      edge.get_ranking(),
+                                                      edge.get_src());
+            allEdges.emplace_back(std::move(edge));
+            allEdges.emplace_back(std::move(reverseEdge));
+        }
+        deleteEdges(&allEdges);
+        return;
+    };
+
+    auto error = [this] (auto &&e) {
+        LOG(ERROR) << "Exception caught: " << e.what();
+        DCHECK(onError_);
+        onError_(Status::Error("Internal error"));
+        return;
+    };
+    std::move(future).via(runner).thenValue(cb).thenError(error);
+}
+
+void DeleteVertexExecutor::deleteEdges(std::vector<storage::cpp2::EdgeKey>* edges) {
+    GraphSpaceID space = ectx()->rctx()->session()->space();
+    auto future = ectx()->storage()->deleteEdges(space, *edges);
+    auto *runner = ectx()->rctx()->runner();
+    auto cb = [this] (auto &&resp) {
+        auto completeness = resp.completeness();
+        if (completeness != 100) {
+            DCHECK(onError_);
+            onError_(Status::Error("Internal Error"));
+            return;
+        }
+        deleteVertex();
+        return;
+    };
+
+    auto error = [this] (auto &&e) {
+        LOG(ERROR) << "Exception caught: " << e.what();
+        DCHECK(onError_);
+        onError_(Status::Error("Internal error"));
+        return;
+    };
+    std::move(future).via(runner).thenValue(cb).thenError(error);
+}
+
+void DeleteVertexExecutor::deleteVertex() {
+    GraphSpaceID space = ectx()->rctx()->session()->space();
+    auto future = ectx()->storage()->deleteVertex(space, vid_);
+    auto *runner = ectx()->rctx()->runner();
+    auto cb = [this] (auto &&resp) {
+        if (!resp.ok()) {
+            DCHECK(onError_);
+            onError_(Status::Error("Internal Error"));
+            return;
+        }
+        DCHECK(onFinish_);
+        onFinish_();
+        return;
+    };
+
+    auto error = [this] (auto &&e) {
+        LOG(ERROR) << "Exception caught: " << e.what();
+        DCHECK(onError_);
+        onError_(Status::Error("Internal error"));
+        return;
+    };
+    std::move(future).via(runner).thenValue(cb).thenError(error);
+}
+
+}   // namespace graph
+}   // namespace nebula
+
diff --git a/src/executor/DeleteVertexExecutor.h b/src/executor/DeleteVertexExecutor.h
new file mode 100644
index 0000000000000000000000000000000000000000..7a2cc2d02b6a4f877d545244f3066e80111c1ebc
--- /dev/null
+++ b/src/executor/DeleteVertexExecutor.h
@@ -0,0 +1,40 @@
+/* Copyright (c) 2019 vesoft inc. All rights reserved.
+ *
+ * This source code is licensed under Apache 2.0 License,
+ * attached with Common Clause Condition 1.0, found in the LICENSES directory.
+ */
+
+#ifndef GRAPH_DELETEVERTEXEXECUTOR_H_
+#define GRAPH_DELETEVERTEXEEXECUTOR_H_
+
+#include "base/Base.h"
+#include "graph/Executor.h"
+
+namespace nebula {
+namespace graph {
+
+class DeleteVertexExecutor final : public Executor {
+public:
+    DeleteVertexExecutor(Sentence *sentence, ExecutionContext *ectx);
+
+    const char* name() const override {
+        return "DeleteVertexExecutor";
+    }
+
+    Status MUST_USE_RESULT prepare() override;
+
+    void execute() override;
+
+private:
+    void deleteEdges(std::vector<storage::cpp2::EdgeKey>* edges);
+    void deleteVertex();
+
+private:
+    DeleteVertexSentence       *sentence_{nullptr};
+    VertexID                   vid_;
+};
+
+}   // namespace graph
+}   // namespace nebula
+
+#endif  // GRAPH_DELETEVERTEXEXECUTOR_H_
diff --git a/src/executor/Executor.cpp b/src/executor/Executor.cpp
index 65b0c26ce056704d2a88e3cc6ce8ad5ed61ee322..3fc6105d2e73b4ec43f76867694fe692bca5a0d7 100644
--- a/src/executor/Executor.cpp
+++ b/src/executor/Executor.cpp
@@ -42,6 +42,7 @@
 #include "graph/FindExecutor.h"
 #include "graph/MatchExecutor.h"
 #include "graph/BalanceExecutor.h"
+#include "graph/DeleteVertexExecutor.h"
 
 namespace nebula {
 namespace graph {
@@ -143,6 +144,9 @@ std::unique_ptr<Executor> Executor::makeExecutor(Sentence *sentence) {
         case Sentence::Kind::kBalance:
             executor = std::make_unique<BalanceExecutor>(sentence, ectx());
             break;
+        case Sentence::Kind::kDeleteVertex:
+            executor = std::make_unique<DeleteVertexExecutor>(sentence, ectx());
+            break;
         case Sentence::Kind::kUnknown:
             LOG(FATAL) << "Sentence kind unknown";
             break;
diff --git a/src/executor/test/CMakeLists.txt b/src/executor/test/CMakeLists.txt
index d8e70e7e06be4c28bdceb4851226cc83fd4a60d9..b24316e36d6a8cf5f1813390f1579eadb3767131 100644
--- a/src/executor/test/CMakeLists.txt
+++ b/src/executor/test/CMakeLists.txt
@@ -204,3 +204,21 @@ nebula_add_test(
         wangle
         gtest
 )
+
+nebula_add_test(
+    NAME
+        deleteVertex_test
+    SOURCES
+        DeleteVertexTest.cpp
+    OBJECTS
+        $<TARGET_OBJECTS:graph_test_common_obj>
+        $<TARGET_OBJECTS:client_cpp_obj>
+        $<TARGET_OBJECTS:adHocSchema_obj>
+        $<TARGET_OBJECTS:http_client_obj>
+        ${GRAPH_TEST_LIBS}
+    LIBRARIES
+        ${THRIFT_LIBRARIES}
+        ${ROCKSDB_LIBRARIES}
+        wangle
+        gtest
+)
diff --git a/src/executor/test/DeleteVertexTest.cpp b/src/executor/test/DeleteVertexTest.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..e9a5f81f6ea5cc88515a300ceeafb488dfd57f61
--- /dev/null
+++ b/src/executor/test/DeleteVertexTest.cpp
@@ -0,0 +1,118 @@
+/* Copyright (c) 2019 vesoft inc. All rights reserved.
+ *
+ * This source code is licensed under Apache 2.0 License,
+ * attached with Common Clause Condition 1.0, found in the LICENSES directory.
+ */
+
+#include "base/Base.h"
+#include "graph/test/TestEnv.h"
+#include "graph/test/TestBase.h"
+#include "graph/test/TraverseTestBase.h"
+#include "meta/test/TestUtils.h"
+
+
+namespace nebula {
+namespace graph {
+
+class DeleteVertexTest : public TraverseTestBase {
+ protected:
+  void SetUp() override {
+    TraverseTestBase::SetUp();
+  }
+
+  void TearDown() override {
+    TraverseTestBase::TearDown();
+  }
+};
+
+TEST_F(DeleteVertexTest, base) {
+    // Check
+    {
+        cpp2::ExecutionResponse resp;
+        auto *fmt = "GO FROM %ld OVER like";
+        auto query = folly::stringPrintf(fmt, players_["Boris Diaw"].vid());
+        auto code = client_->execute(query, resp);
+        ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
+        std::vector<std::tuple<int64_t>> expected = {
+            {players_["Tony Parker"].vid()},
+            {players_["Tim Duncan"].vid()},
+        };
+        ASSERT_TRUE(verifyResult(resp, expected));
+    }
+    {
+        cpp2::ExecutionResponse resp;
+        auto &player = players_["Tony Parker"];
+        auto *fmt = "FETCH PROP ON player %ld YIELD player.name, player.age";
+        auto query = folly::stringPrintf(fmt, player.vid());
+        auto code = client_->execute(query, resp);
+        ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
+        std::vector<std::tuple<std::string, int64_t>> expected = {
+            {player.name(), player.age()},
+        };
+        ASSERT_TRUE(verifyResult(resp, expected));
+    }
+    {
+        cpp2::ExecutionResponse resp;
+        auto &player = players_["Tony Parker"];
+        auto &serve = player.serves()[0];
+        auto &team = teams_[std::get<0>(serve)];
+        auto *fmt = "FETCH PROP ON serve %ld->%ld"
+                    " YIELD serve.start_year, serve.end_year";
+        auto query = folly::stringPrintf(fmt, player.vid(), team.vid());
+        auto code = client_->execute(query, resp);
+        ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
+        std::vector<std::tuple<int64_t, int64_t>> expected = {
+            {std::get<1>(serve), std::get<2>(serve)},
+        };
+        ASSERT_TRUE(verifyResult(resp, expected));
+    }
+    // Delete vertex
+    {
+        cpp2::ExecutionResponse resp;
+        auto *fmt = "DELETE VERTEX %ld";
+        auto query = folly::stringPrintf(fmt, players_["Tony Parker"].vid());
+        auto code = client_->execute(query, resp);
+        ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
+    }
+    // Check again
+    {
+        cpp2::ExecutionResponse resp;
+        auto *fmt = "GO FROM %ld OVER like";
+        auto query = folly::stringPrintf(fmt, players_["Boris Diaw"].vid());
+        auto code = client_->execute(query, resp);
+        ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
+        std::vector<std::tuple<int64_t>> expected = {
+            {players_["Tim Duncan"].vid()},
+        };
+        ASSERT_TRUE(verifyResult(resp, expected));
+    }
+    {
+        cpp2::ExecutionResponse resp;
+        auto &player = players_["Tony Parker"];
+        auto *fmt = "FETCH PROP ON player %ld YIELD player.name, player.age";
+        auto query = folly::stringPrintf(fmt, player.vid());
+        auto code = client_->execute(query, resp);
+        ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
+        std::vector<std::tuple<std::string, int64_t>> expected = {
+        };
+        ASSERT_TRUE(verifyResult(resp, expected));
+    }
+    {
+        cpp2::ExecutionResponse resp;
+        auto &player = players_["Tony Parker"];
+        auto &serve = player.serves()[0];
+        auto &team = teams_[std::get<0>(serve)];
+        auto *fmt = "FETCH PROP ON serve %ld->%ld"
+                    " YIELD serve.start_year, serve.end_year";
+        auto query = folly::stringPrintf(fmt, player.vid(), team.vid());
+        auto code = client_->execute(query, resp);
+        ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
+        std::vector<std::tuple<int64_t, int64_t>> expected = {
+        };
+        ASSERT_TRUE(verifyResult(resp, expected));
+    }
+}
+
+}  // namespace graph
+}  // namespace nebula
+
diff --git a/src/parser/MutateSentences.cpp b/src/parser/MutateSentences.cpp
index cd6c44bc7c990f8f6ffd988a952c7abb533b0f07..8a091fa32e38b2f48f7ee56a2069d220f2b76884 100644
--- a/src/parser/MutateSentences.cpp
+++ b/src/parser/MutateSentences.cpp
@@ -230,11 +230,7 @@ std::string DeleteVertexSentence::toString() const {
     std::string buf;
     buf.reserve(256);
     buf += "DELETE VERTEX ";
-    buf += vidList_->toString();
-    if (whereClause_ != nullptr) {
-        buf += " ";
-        buf += whereClause_->toString();
-    }
+    buf += vid_->toString();
     return buf;
 }
 
diff --git a/src/parser/MutateSentences.h b/src/parser/MutateSentences.h
index 0e75912687e6b4b1c8104a74ca065d3d4827df75..02bdea43425c199a37b5070acb891d935b453b6c 100644
--- a/src/parser/MutateSentences.h
+++ b/src/parser/MutateSentences.h
@@ -405,28 +405,19 @@ private:
 
 class DeleteVertexSentence final : public Sentence {
 public:
-    explicit DeleteVertexSentence(VertexIDList *vidList) {
-        vidList_.reset(vidList);
+    explicit DeleteVertexSentence(Expression *vid) {
+        vid_.reset(vid);
         kind_ = Kind::kDeleteVertex;
     }
 
-    auto vidList() const {
-        return vidList_->vidList();
-    }
-
-    void setWhereClause(WhereClause *clause) {
-        whereClause_.reset(clause);
-    }
-
-    const WhereClause* whereClause() const {
-        return whereClause_.get();
+    Expression* vid() const {
+        return vid_.get();
     }
 
     std::string toString() const override;
 
 private:
-    std::unique_ptr<VertexIDList>               vidList_;
-    std::unique_ptr<WhereClause>                whereClause_;
+    std::unique_ptr<Expression>                  vid_;
 };
 
 
diff --git a/src/parser/parser.yy b/src/parser/parser.yy
index e5fb90dacaba4f857199360d13bed6848bd05307..9f7ad2b18f68bd3ce991e97a97986784216404d9 100644
--- a/src/parser/parser.yy
+++ b/src/parser/parser.yy
@@ -1155,9 +1155,8 @@ update_edge_sentence
     ;
 
 delete_vertex_sentence
-    : KW_DELETE KW_VERTEX vid_list where_clause {
+    : KW_DELETE KW_VERTEX vid {
         auto sentence = new DeleteVertexSentence($3);
-        sentence->setWhereClause($4);
         $$ = sentence;
     }
     ;
diff --git a/src/parser/test/ParserTest.cpp b/src/parser/test/ParserTest.cpp
index efbf5f6a00653b414ab3fe43cb4214f250b5d30f..8caa03e9f2c2faf20d644714fcc167331096d8ed 100644
--- a/src/parser/test/ParserTest.cpp
+++ b/src/parser/test/ParserTest.cpp
@@ -662,19 +662,7 @@ TEST(Parser, DeleteVertex) {
     }
     {
         GQLParser parser;
-        std::string query = "DELETE VERTEX 123,456,789";
-        auto result = parser.parse(query);
-        ASSERT_TRUE(result.ok()) << result.status();
-    }
-    {
-        GQLParser parser;
-        std::string query = "DELETE VERTEX 12345 WHERE salary > 10000";
-        auto result = parser.parse(query);
-        ASSERT_TRUE(result.ok()) << result.status();
-    }
-    {
-        GQLParser parser;
-        std::string query = "DELETE VERTEX 123,456,789 WHERE salary > 10000";
+        std::string query = "DELETE VERTEX hash(\"zhangsan\")";
         auto result = parser.parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }